Multiplex assessment of protein variant abundance by massively parallel sequencing VAMP-seq - multiplex assay that uses fluorescent reporters to measure the steady-state abundance of protein variants in cultured human cells (each cellexpresses a single variant directly fused to EGFP…the stability of the variant dictates the abundance of the EGFP fusion and, accordingly, the green fluorescence signal of the cell) - used to assess PTEN and TPMT variants
#plots VAMP-seq score vs abundance_class
VAMP_abundance <- ggplot(ff, aes(x=abundance_class, y=score, fill=protein)) + geom_violin(draw_quantiles = 0.5)+ylab("VAMP-seq score")+xlab("Abundance Class")+theme(legend.title=element_blank(), panel.grid.major = element_line(colour = "grey"), panel.grid.minor = element_line(colour = "grey"))+ggtitle("VAMP-seq scores for each abundance classification")+geom_point(data=data.frame(x="wt-like", y=1, protein = "PTEN"), aes(x,y), colour="black", size=1.5, show.legend=FALSE)+annotate("text", x = "wt-like", y=1.09, label = "WT",colour= "black", size = 4) + scale_y_continuous(minor_breaks = seq(-2, 2, .25))+theme_bw()
plot(VAMP_abundance)

# graph VAMP-seq scores relative to variant position in protein
#pten
pten1_proc_wt <- pten1_proc[!is.na(pten1_proc$position),]
pten1_proc_wt$secondary_struct <- ifelse(is.na(pten1_proc_wt$helix), "unknown",
ifelse(pten1_proc_wt$helix==1, "helix",
ifelse(pten1_proc_wt$sheet==1, "sheet",
ifelse(pten1_proc_wt$helix==0, "neither",
"unknown"))))
pten_pos <- ggplot(pten1_proc_wt, aes(x=position, y=score, colour=secondary_struct))+ geom_point(size=.3) + scale_x_continuous(minor_breaks = seq(0, 420, 5)) + scale_color_manual(values=c("#FF4848", "#00C853", "#5757FF", "#A9A9A9")) +ylab("VAMP-seq score")+xlab("Position in PTEN")+labs(colour="Secondary Structure")+ggtitle("PTEN scores in relation to protein structure") + geom_vline(xintercept=27, color="black", size=.1) + geom_vline(xintercept=55, color="black", size=.1) + geom_vline(xintercept=70, color="black", size=.1) + geom_vline(xintercept=85, color="black", size=.1) + geom_vline(xintercept=164.5, color="black", size=.1) + geom_vline(xintercept=212, color="black", size=.1) + geom_vline(xintercept=267.5, color="black", size=.1) + geom_vline(xintercept=343.5, color="black", size=.1)+theme_bw()
pten_hydro <- ggplot(pten1_proc_wt, aes(x=position, y=score, colour=(hydro2-hydro1)))+ geom_point(size=.3, alpha = 0.3) + scale_x_continuous(minor_breaks = seq(0, 420, 5)) + ylab("VAMP-seq score")+xlab("Position in PTEN")+labs(colour="Hydrophobicity")+ggtitle("PTEN scores in relation to change in hydrophobicity") + geom_vline(xintercept=27, color="black", size=.1) + geom_vline(xintercept=55, color="black", size=.1) + geom_vline(xintercept=70, color="black", size=.1) + geom_vline(xintercept=85, color="black", size=.1) + geom_vline(xintercept=164.5, color="black", size=.1) + geom_vline(xintercept=212, color="black", size=.1) + geom_vline(xintercept=267.5, color="black", size=.1) + geom_vline(xintercept=343.5, color="black", size=.1)
#tpmt
tpmt1_proc_wt <- tpmt1_proc[!is.na(tpmt1_proc$position),]
tpmt1_proc_wt$secondary_struct <- ifelse(is.na(tpmt1_proc_wt$helix), "unknown",
ifelse(tpmt1_proc_wt$helix==1, "helix",
ifelse(tpmt1_proc_wt$sheet==1, "sheet",
ifelse(tpmt1_proc_wt$helix==0, "neither",
"unknown"))))
tpmt_pos <- ggplot(tpmt1_proc_wt, aes(x=position, y=score, colour=secondary_struct))+ geom_point(size=.3) + scale_x_continuous(minor_breaks = seq(0, 405, 5)) + scale_color_manual(values=c("#FF4848", "#00C853", "#5757FF", "#A9A9A9")) +ylab("VAMP-seq score")+xlab("Position in TPMT")+labs(colour="Secondary Structure")+ggtitle("TPMT scores in relation to protein structure") + geom_vline(xintercept=47, color="black", size=.1) + geom_vline(xintercept=78, color="black", size=.1) + geom_vline(xintercept=122.5, color="black", size=.1) + geom_vline(xintercept=140, color="black", size=.1) + geom_vline(xintercept=165, color="black", size=.1) + geom_vline(xintercept=194, color="black", size=.1) + geom_vline(xintercept=209, color="black", size=.1)+theme_bw()
tpmt_colors <- tpmt1_proc_wt
#[order(position, variant),]
tpmt_colors$fact <- rep(10, nrow(tpmt_colors))
temp <- 1
for(i in 1:(length(tpmt_colors$fact)-1)) {
if (tpmt_colors$secondary_struct[i] != tpmt_colors$secondary_struct[i+1]) {
tpmt_colors$fact[i] <- temp
temp <- temp + 1
} else {
tpmt_colors$fact[i] <- temp
}
}
tpmt_colors$fact[length(tpmt_colors$fact)] <- temp
# cc <- 0
# for(i in 1:(length(tpmt_colors$fact)-1)) {
# if (tpmt_colors$fact[i] != tpmt_colors$fact[i+1]) {
# print(cc)
# cc <- 0
# } else {
# cc <- cc + 1
# }
# }
tpmt_pos_vp <- ggplot(tpmt_colors, aes(x=position, y=score))+ geom_violin(data=tpmt_colors[c(1:2783, 2798:4000),], aes(fill=as.character(fact), colour = factor(TRUE)), draw_quantiles = c(0.5), scale = "width") +
scale_fill_manual(values=c("1" = "#A9A9A9", "2" = "#00C853", "3" = "#FF4848", "4" = "#00C853","5" = "#FF4848", "6" = "#00C853","7" = "#5757FF", "8" = "#00C853","9" = "#FF4848","10" = "#00C853","11" = "#5757FF", "12" = "#00C853","13" = "#FF4848", "14" = "#00C853", "15" = "#5757FF", "16" = "#00C853", "17" = "#5757FF", "18" = "#00C853", "19" = "#5757FF", "20" = "#00C853", "21" = "#5757FF", "22" = "#00C853", "23" = "#FF4848", "24" = "#5757FF", "25" = "#00C853", "26" = "#FF4848", "27" = "#00C853", "28" = "#5757FF", "29" = "#00C853", "30" = "#5757FF", "31" = "#00C853")) + scale_colour_manual(values = c("black")) + scale_x_continuous(minor_breaks = seq(0, 405, 5)) + ylab("VAMP-seq score")+xlab("Position in TPMT")+labs(colour="Secondary Structure")+ggtitle("TPMT scores in relation to protein structure") + geom_vline(xintercept=47, color="black", size=.1) + geom_vline(xintercept=78, color="black", size=.1) + geom_vline(xintercept=122.5, color="black", size=.1) + geom_vline(xintercept=140, color="black", size=.1) + geom_vline(xintercept=165, color="black", size=.1) + geom_vline(xintercept=194, color="black", size=.1) + geom_vline(xintercept=209, color="black", size=.1)
pten_hydro1 <- ggplot(pten1_proc_wt, aes(y=score, x=(hydro2-hydro1)))+ geom_point(size=0.5, alpha = 0.3) + ylab("Hydrophobicity")+xlab("VAMP-seq score")+ggtitle("PTEN scores in relation to change in hydrophobicity")
pten_aa_spread <- ggplot(pten1_proc_wt[2:288,], aes(y=score, x=start)) + geom_violin(draw_quantiles=c(0.5))
pten_aa_spread1 <- ggplot(pten1_proc_wt[2:288,], aes(y=score, x=start)) + geom_point(size = 0.5)
plot(pten_pos)

plot(tpmt_pos)

#plot(tpmt_pos_vp)
#plot(pten_hydro)
#plot(pten_hydro1)
#plot(pten_aa_spread)
#plot(pten_aa_spread1)
# graph VAMP-seq scores relative to variant position in protein
#pten
pten1_hbond <- pten1_proc[!is.na(pten1_proc$hbond_sum),]
pten1_hbond$secondary_struct <- ifelse(is.na(pten1_hbond$helix), "unknown",
ifelse(pten1_hbond$helix==1, "helix",
ifelse(pten1_hbond$sheet==1, "sheet",
ifelse(pten1_hbond$helix==0, "neither",
"unknown"))))
pten_plot_hbond <- ggplot(pten1_hbond, aes(x=hbond_sum, y=score, colour=secondary_struct))+ geom_point(alpha=0.4) + ylab("VAMP-seq score")+xlab("DSSP Sum of hydrogen bonds")+ggtitle("PTEN scores in relation to hydrogen bonding") + scale_color_manual(values=c("#FF4848", "#696969", "#5757FF")) + labs(colour="Secondary Structure")
plot(pten_plot_hbond)

pten_plot_hbond1 <- ggplot(pten1_hbond, aes(x=hbond_sum, y=score))+ geom_point(alpha = 0.2) + ylab("VAMP-seq score")+xlab("DSSP Sum of hydrogen bonds")+ggtitle("PTEN scores in relation to hydrogen bonding")
# was in aes, ggplot function call ---> colour=secondary_struct
#scale_color_manual(values=c("#FF4848", "#00C853", "#5757FF", "#A9A9A9")) + labs(colour="Secondary Structure")+
plot(pten_plot_hbond1)

#less hydrogen bonds ~ higher abundance
#TPMT
tpmt_sum <- summarySE(tpmt1_proc_wt, measurevar="score", groupvars="position")
#head(tpmt_sum)
tpmt_pos_mean <- ggplot(tpmt_sum, aes(x=position, y=score))+ geom_bar(position=position_dodge(), stat="identity", colour="#999999") + geom_errorbar(aes(ymin=score-sd, ymax = score+sd), width=1, size=0.3, position=position_dodge()) +ylab("VAMP-seq score")+theme(axis.title.x = element_blank(), axis.text.x = element_blank()) + scale_x_continuous(breaks = seq(0, 245, 10), expand = c(0,0)) + scale_y_continuous(expand = c(0,0))
#factor(position) is getting rid of some positions altogether on the graph
#tpmt_pos_mean <- ggplot(tpmt_sum, aes(x=factor(position), y=score))+ geom_bar(position=position_dodge(), stat="identity", colour="#999999") + geom_errorbar(aes(ymin=score-sd, ymax = score+sd), width=0.001, position=position_dodge()) +ylab("VAMP-seq score")+theme(axis.title.x = element_blank(), axis.text.x = element_blank()) + scale_x_discrete(breaks = seq(0, 250, 10))
tpmt_heat <- ggplot(tpmt1_proc_wt, aes(position, end)) + geom_tile(aes(fill=score)) + scale_fill_gradientn(colours = c("#3F7CB9", "#FFEAF3", "#B21F4E"), values = scales::rescale(c(-0.7, 0.2, 1, 1.3, 2.03)))+ scale_x_continuous(breaks = seq(0, 245, 10), expand=c(0,0)) + theme(legend.position='bottom')+xlab("Position in TPMT") + scale_y_discrete(expand = c(0,0))
#scale_fill_gradient2(low="#3F7CB9", mid="white", high="#B21F4E", midpoint=1)
#scale_fill_distiller(palette= "RdBu")
tpmt_dssp_schematic <- ggplot() + ggtitle("TPMT mean abundance scores") +
geom_segment(aes(x = 1, y = 0, xend = max(tpmt1_data$position)), yend = 0, size = 1, color = "grey70") +
geom_point(data = tpmt1_data, aes(x = position, y = 0), color = "black", size = 1.8) +
geom_point(data = subset(tpmt1_data, sheet == 1), aes(x = position, y = 0), color = "pink", size = 1.5) +
geom_point(data = subset(tpmt1_data, helix == 1), aes(x = position, y = 0), color = "cyan", size = 1.5) +
scale_x_continuous(breaks = seq(0, 245, 10), expand = c(0,0)) +
scale_y_continuous(breaks = NULL, expand = c(0,0)) +xlab(NULL) + ylab(NULL) +
theme(panel.border = element_blank(), axis.text.x = element_blank(), axis.text.y = element_blank())
#plots
plot(tpmt_pos_mean)

plot(tpmt_heat)

tpmt_dssp_schematic

#+ geom_vline(xintercept=185, color="black", size=.1) + geom_vline(xintercept=350, color="black", size=.1)
#grouping all variants in the same secondary structure together
tpmt_aa_sum <- summarySE(tpmt_colors, measurevar="score", groupvars="fact")
tpmt_aa_mean <- ggplot(tpmt_aa_sum, aes(x=fact, y=score))+ geom_bar(position=position_dodge(), stat="identity", colour="#999999") + geom_errorbar(aes(ymin=score-sd, ymax = score+sd), width=1, size=0.3, position=position_dodge()) +ylab("VAMP-seq score")+theme(axis.text.x = element_blank()) + scale_x_discrete(breaks = seq(0, 245, 10)) + xlab("each bar is a different secondary structure")
plot(tpmt_aa_mean)

#PTEN
pten_sum <- summarySE(pten1_proc_wt, measurevar="score", groupvars="position")
NaNs produced
#head(pten_sum)
pten_pos_mean <- ggplot(pten_sum, aes(x=position, y=score))+ geom_bar(position=position_dodge(), stat="identity", colour="#999999") + geom_errorbar(aes(ymin=score-sd, ymax = score+sd), width=1, size=0.3, position=position_dodge()) +ylab("VAMP-seq score")+theme(axis.title.x = element_blank(), axis.text.x = element_blank()) + scale_x_continuous(breaks = seq(0, 403, 20), expand = c(0,0)) + scale_y_continuous(expand = c(0,0)) + geom_vline(xintercept=185, color="black", size=.1) + geom_vline(xintercept=350, color="black", size=.1)
pten_heat <- ggplot(pten1_proc_wt, aes(position, end)) + geom_tile(aes(fill=score)) + scale_fill_gradientn(colours = c("#3F7CB9", "#FFEAF3", "#B21F4E"), values = scales::rescale(c(-0.23, 0.42, 1, 1.2, 1.47)))+ scale_x_continuous(breaks = seq(0, 403, 20), expand=c(0,0)) + theme(legend.position='bottom')+xlab("Position in TPMT") + scale_y_discrete(expand = c(0,0))
#c(-0.7, 0.2, 1, 1.3, 2.03)
#c(-0.23, 0.42, 1, 1.2, 1.47)
pten_extra <- read.table(file = '~/leklab/leklab/PTEN_positional_data.tsv', sep = '\t', header = TRUE)
pten_dssp_schematic <- ggplot() + ggtitle("PTEN mean abundance scores") +
geom_segment(aes(x = 1, y = 0, xend = max(pten_extra$position)), yend = 0, size = 1, color = "grey70") +
geom_point(data = subset(pten_extra, !is.na(xca)), aes(x = position, y = 0), color = "black", size = 1.8) +
geom_point(data = subset(pten_extra, sheet == 1), aes(x = position, y = 0), color = "pink", size = 1.5) +
geom_point(data = subset(pten_extra, helix == 1), aes(x = position, y = 0), color = "cyan", size = 1.5) +
scale_x_continuous(breaks = seq(0, 403, 20), expand = c(0,0)) +
scale_y_continuous(breaks = NULL, expand = c(0,0)) +xlab(NULL) + ylab(NULL) +
theme(panel.border = element_blank(), axis.text.x = element_blank(), axis.text.y = element_blank())
#plots
plot(pten_pos_mean)

plot(pten_heat)

pten_dssp_schematic

#method1 (basic, for visualizing in rstudio)
grid.newpage()
grid.draw(rbind(ggplotGrob(tpmt_dssp_schematic), ggplotGrob(tpmt_pos_mean), ggplotGrob(tpmt_heat), size = "last"))
Removed 1 rows containing missing values (geom_segment).Removed 1 rows containing missing values (geom_point).

grid.newpage()
grid.draw(rbind(ggplotGrob(pten_dssp_schematic), ggplotGrob(pten_pos_mean), ggplotGrob(pten_heat), size = "last"))
Removed 12 rows containing missing values (geom_errorbar).

#method2 (use for final layout, size specification, download)
gA=ggplot_gtable(ggplot_build(tpmt_pos_mean))
gB=ggplot_gtable(ggplot_build(tpmt_heat))
gC=ggplot_gtable(ggplot_build(tpmt_dssp_schematic))
Removed 1 rows containing missing values (geom_segment).Removed 1 rows containing missing values (geom_point).
ga=ggplot_gtable(ggplot_build(pten_pos_mean))
Removed 12 rows containing missing values (geom_errorbar).
gb=ggplot_gtable(ggplot_build(pten_heat))
gc=ggplot_gtable(ggplot_build(pten_dssp_schematic))
maxWidth = grid::unit.pmax(gA$widths, gB$widths, gC$widths, ga$widths, gb$widths, gc$widths)
gA$widths <- as.list(maxWidth)
gB$widths <- as.list(maxWidth)
gC$widths <- as.list(maxWidth)
ga$widths <- as.list(maxWidth)
gb$widths <- as.list(maxWidth)
gc$widths <- as.list(maxWidth)
grid.newpage()
#storing, with specified widths!!
pdf('pten_tpmt_mean_heat.pdf', width=8, height=6)
grid.arrange(arrangeGrob(gC,gA,gB,nrow=3,heights=c(.1,.3,.8)))
grid.arrange(arrangeGrob(gc,ga,gb,nrow=3,heights=c(.1,.3,.8)))
dev.off()
quartz_off_screen
2

#plotting mean score vs variant changed to
tpmt_end_sum <- summarySE(tpmt1_proc_wt, measurevar="score", groupvars="end")
tpmt_end_mean <- ggplot(tpmt_end_sum, aes(x=end, y=score)) +
geom_bar(position=position_dodge(), stat="identity", colour="#999999") +
geom_errorbar(aes(ymin=score-sd, ymax=score+sd), width=0.001, position=position_dodge()) +
ylab("mean abundance") + xlab("variant amino acid")
plot(tpmt_end_mean)

set.seed(153)
jitter <- position_jitter(width = 1, height = NULL)
jitter1 <-position_jitter(width = 0.08, height = NULL)
jitter2 <- position_jitter(width=0.13, height = NULL)
twenty_color = c("#D02028", "#E1A12F", "#EDD941", "#F2F08E", "#EEC898", "#BCDDAE", "#A4C33B", "#76C158", "#85782E", "#315935", "#53958B", "#A1DAE0", "#486EB6", "#E6A3B4", "#C5A0CA", "#554DA0", "#99247E", "#402059", "#82421B", "#7E807E", 'black')
#pten_k_spread1 <- ggplot(pten1_proc_wt, aes(y=score, x=start)) + geom_violin(draw_quantiles=c(0.5), data=subset(pten1_proc_wt, start== "K"), aes(group=factor(position))) + xlab("Position in PTEN") + ggtitle("Lysine variant abundance scores")
pten_k_spread1 <- ggplot(pten1_proc_wt, aes(y=score, x=factor(position), colour = end)) + geom_violin(draw_quantiles=c(0.5), data=subset(pten1_proc_wt, start== "K"), aes(group=factor(position)), scale = "width") + xlab("Position in PTEN") + ggtitle("Lysine variant abundance scores")+ geom_point(data=subset(pten1_proc_wt, start== "K"), aes(x=factor(position), y=score), alpha = 0.85, position=jitter2) + scale_color_manual(values=twenty_color)
pten_k_aa <- ggplot(pten1_proc_wt, aes(y=score, x=end, colour = end)) + geom_violin(draw_quantiles=c(0.5), data=subset(pten1_proc_wt, start== "K"), aes(group=end), scale = "width") + xlab("Amino acid") + ggtitle("Lysine variant abundance scores")+ geom_point(data=subset(pten1_proc_wt, start== "K"), aes(x=end, y=score), alpha = 0.75, position=jitter1) + scale_color_manual(values=twenty_color)
pten_g_spread1 <- ggplot(pten1_proc_wt, aes(y=score, x=factor(position), colour = end)) + geom_violin(draw_quantiles=c(0.5), data=subset(pten1_proc_wt, start== "G"), aes(group=factor(position)), scale = "width") + xlab("Position in PTEN") + ggtitle("Glycine variant abundance scores")+ geom_point(data=subset(pten1_proc_wt, start== "G"), aes(x=factor(position), y=score), alpha = 0.85, position=jitter2) + scale_color_manual(values=twenty_color)
pten_g_aa <- ggplot(pten1_proc_wt, aes(y=score, x=end, colour = end)) + geom_violin(draw_quantiles=c(0.5), data=subset(pten1_proc_wt, start== "G"), aes(group=end), scale = "width") + xlab("Amino acid") + ggtitle("Glycine variant abundance scores")+ geom_point(data=subset(pten1_proc_wt, start== "G"), aes(x=end, y=score), alpha = 0.75, position=jitter1) + scale_color_manual(values=twenty_color)
pten_g_hydrodiff <- ggplot(pten1_proc_wt, aes(y=score, x=factor(position), colour = (hydro2-hydro1))) + geom_violin(draw_quantiles=c(0.5), data=subset(pten1_proc_wt, start== "G"), aes(group=factor(position)), scale = "width") + xlab("Position in PTEN") + ggtitle("Glycine variant abundance scores w/ hydrophobicity change")+ geom_point(data=subset(pten1_proc_wt, start== "G"), aes(x=factor(position), y=score), alpha = 0.85, position=jitter2) + scale_color_distiller(palette = "Spectral")
pten_c_spread <- ggplot(pten1_proc_wt, aes(y=score, x=position)) + geom_point(data=subset(pten1_proc_wt, start== "C")) + xlab("Position in PTEN") + ggtitle("Cysteine variant abundance scores")
#experiment_orig
#pten_c_spread1 <- ggplot(pten1_proc_wt, aes(y=score, x=position, colour = end)) + geom_violin(draw_quantiles=c(0.5), data=subset(pten1_proc_wt, start== "C"), aes(group=position%%450), scale = "width") + xlab("Position in PTEN") + ggtitle("Cysteine variant abundance scores")+ geom_point(data=subset(pten1_proc_wt, start== "C"), aes(x=position, y=score), alpha = 0.75, position=jitter) + scale_color_manual(values=c("#D02028", "#E1A12F", "#EDD941", "#F2F08E", "#EEC898", "#BCDDAE", "#A4C33B", "#76C158", "#85782E", "#315935", "#53958B", "#A1DAE0", "#486EB6", "#E6A3B4", "#C5A0CA", "#554DA0", "#99247E", "#402059", "#82421B", "#7E807E", 'black'))
#, scale = "count"
#+ geom_point(data=subset(pten1_proc_wt, start== "C"), aes(x=position, y=score), alpha = 0.5)
pten_c_spread1 <- ggplot(pten1_proc_wt, aes(y=score, x=position, colour = end)) + geom_violin(draw_quantiles=c(0.5), data=subset(pten1_proc_wt, start== "C"), aes(group=position%%450), scale = "width") + xlab("Position in PTEN") + ggtitle("Cysteine variant abundance scores")+ geom_point(data=subset(pten1_proc_wt, start== "C"), aes(x=position, y=score), alpha = 0.75, position=jitter1) + scale_color_manual(values=twenty_color)
pten_c_aa <- ggplot(pten1_proc_wt, aes(y=score, x=end, colour = end)) + geom_violin(draw_quantiles=c(0.5), data=subset(pten1_proc_wt, start== "C"), aes(group=end), scale = "width") + xlab("Amino acid") + ggtitle("Cysteine variant abundance scores")+ geom_point(data=subset(pten1_proc_wt, start== "C"), aes(x=end, y=score), alpha = 0.75, position=jitter1) + scale_color_manual(values=twenty_color)
pten_c_hydrodiff <- ggplot(pten1_proc_wt, aes(y=score, x=position, colour = (hydro2-hydro1))) + geom_violin(draw_quantiles=c(0.5), data=subset(pten1_proc_wt, start== "C"), aes(group=position%%450), scale = "width") + xlab("Position in PTEN") + ggtitle("Cysteine variant abundance scores w/ hydrophobicity change")+ geom_point(data=subset(pten1_proc_wt, start== "C"), aes(x=position, y=score), alpha = 0.75, position=jitter1) + scale_color_distiller(palette = "Spectral")
#in in geom_violin(aes()) -> colour = hydro1
#pten_s_spread <- ggplot(pten1_proc_wt, aes(y=score, x=position)) + geom_point(data=subset(pten1_proc_wt, start== "S")) + xlab("Position in PTEN") + ggtitle("Serine variant abundance scores")
#pten_s_spread1_old <- ggplot(pten1_proc_wt, aes(y=score, x=start)) + geom_violin(draw_quantiles=c(0.5), data=subset(pten1_proc_wt, start== "S"), aes(group=factor(position))) + xlab("Position in PTEN") + ggtitle("Serine variant abundance scores")
pten_s_spread1 <- ggplot(pten1_proc_wt, aes(y=score, x=factor(position), colour = end)) + geom_violin(draw_quantiles=c(0.5), data=subset(pten1_proc_wt, start== "S"), aes(group=factor(position)), scale = "width") + xlab("Position in PTEN") + ggtitle("Serine variant abundance scores")+ geom_point(data=subset(pten1_proc_wt, start== "S"), aes(x=factor(position), y=score), alpha = 0.85, position=jitter2) + scale_color_manual(values=twenty_color)
pten_s_aa <- ggplot(pten1_proc_wt, aes(y=score, x=end, colour = end)) + geom_violin(draw_quantiles=c(0.5), data=subset(pten1_proc_wt, start== "S"), aes(group=end), scale = "width") + xlab("Amino acid") + ggtitle("Serine variant abundance scores")+ geom_point(data=subset(pten1_proc_wt, start== "S"), aes(x=end, y=score), alpha = 0.75, position=jitter1) + scale_color_manual(values=twenty_color)
pten_s_hydrodiff <- ggplot(pten1_proc_wt, aes(y=score, x=factor(position), colour = (hydro2-hydro1))) + geom_violin(draw_quantiles=c(0.5), data=subset(pten1_proc_wt, start== "S"), aes(group=factor(position)), scale = "width") + xlab("Position in PTEN") + ggtitle("Serine variant abundance scores w/ hydrophobicity change")+ geom_point(data=subset(pten1_proc_wt, start== "S"), aes(x=factor(position), y=score), alpha = 0.85, position=jitter2) + scale_color_distiller(palette = "Spectral")
#graphing abundance vs change in hydrophobicity
pten_s_hh_hydrodiff <- ggplot(pten1_proc_wt, aes(y=score, x=factor(hydro2-hydro1), colour = (hydro2-hydro1))) + geom_violin(draw_quantiles=c(0.5), data=subset(pten1_proc_wt, start== "S"), aes(group=factor(hydro2-hydro1)), scale = "width") + xlab("Change in hydrophobicity") + ggtitle("Serine variant abundance scores")+ geom_point(data=subset(pten1_proc_wt, start== "S"), aes(x=factor(hydro2-hydro1), y=score), alpha = 0.75, position=jitter1)
#pten_s_aa_hydrodiff <- ggplot(pten1_proc_wt, aes(y=score, x=end, colour = (hydro2-hydro1))) + geom_violin(draw_quantiles=c(0.5), data=subset(pten1_proc_wt, start== "S"), aes(group=end), scale = "width") + xlab("Amino acid") + ggtitle("Serine variant abundance scores")+ geom_point(data=subset(pten1_proc_wt, start== "S"), aes(x=end, y=score), alpha = 0.75, position=jitter1)
#pten_s_aa_voldiff <- ggplot(pten1_proc_wt, aes(y=score, x=end, colour = voldiff)) + geom_violin(draw_quantiles=c(0.5), data=subset(pten1_proc_wt, start== "S"), aes(group=end), scale = "width") + xlab("Amino acid") + ggtitle("Serine variant abundance scores")+ geom_point(data=subset(pten1_proc_wt, start== "S"), aes(x=end, y=score), alpha = 0.75, position=jitter1)
#pten_s_aa_poldiff <- ggplot(pten1_proc_wt, aes(y=score, x=end, colour = polaritydiff)) + geom_violin(draw_quantiles=c(0.5), data=subset(pten1_proc_wt, start== "S"), aes(group=end), scale = "width") + xlab("Amino acid") + ggtitle("Serine variant abundance scores")+ geom_point(data=subset(pten1_proc_wt, start== "S"), aes(x=end, y=score), alpha = 0.75, position=jitter1)
#pten_s_aa_weightdiff <- ggplot(pten1_proc_wt, aes(y=score, x=end, colour = weightdiff)) + geom_violin(draw_quantiles=c(0.5), data=subset(pten1_proc_wt, start== "S"), aes(group=end), scale = "width") + xlab("Amino acid") + ggtitle("Serine variant abundance scores")+ geom_point(data=subset(pten1_proc_wt, start== "S"), aes(x=end, y=score), alpha = 0.75, position=jitter1)
#specific amino acid tests
##plot(pten_k_spread)
##plot(pten_g_spread)
##plot(pten_c_spread)
##plot(pten_s_spread)
##plot(pten_s_spread1_old)
#plot(pten_s_hh_hydrodiff) #probably not very useful... does not take into account position anymore
##plot(pten_s_aa_hydrodiff)
##plot(pten_s_aa_voldiff)
##plot(pten_s_aa_poldiff)
##plot(pten_s_aa_weightdiff)
plot(pten_c_spread1)

plot(pten_c_aa)

plot(pten_c_hydrodiff)

plot(pten_s_spread1)

plot(pten_s_aa)

plot(pten_s_hydrodiff)

plot(pten_g_spread1)

plot(pten_g_aa)

plot(pten_g_hydrodiff)

plot(pten_k_spread1)

plot(pten_k_aa)

pten_a_spread1 <- ggplot(pten1_proc_wt, aes(y=score, x=factor(position), colour = end)) + geom_violin(draw_quantiles=c(0.5), data=subset(pten1_proc_wt, start== "A"), aes(group=factor(position)), scale = "width") + xlab("Position in PTEN") + ggtitle("Alanine variant abundance scores")+ geom_point(data=subset(pten1_proc_wt, start== "A"), aes(x=factor(position), y=score), alpha = 0.85, position=jitter2) + scale_color_manual(values=twenty_color)
pten_a_aa <- ggplot(pten1_proc_wt, aes(y=score, x=end, colour = end)) + geom_violin(draw_quantiles=c(0.5), data=subset(pten1_proc_wt, start== "A"), aes(group=end), scale = "width") + xlab("Amino acid") + ggtitle("Alanine variant abundance scores")+ geom_point(data=subset(pten1_proc_wt, start== "A"), aes(x=end, y=score), alpha = 0.75, position=jitter1) + scale_color_manual(values=twenty_color)
pten_r_spread1 <- ggplot(pten1_proc_wt, aes(y=score, x=factor(position), colour = end)) + geom_violin(draw_quantiles=c(0.5), data=subset(pten1_proc_wt, start== "R"), aes(group=factor(position)), scale = "width") + xlab("Position in PTEN") + ggtitle("Arganine variant abundance scores")+ geom_point(data=subset(pten1_proc_wt, start== "R"), aes(x=factor(position), y=score), alpha = 0.85, position=jitter2) + scale_color_manual(values=twenty_color)
pten_r_aa <- ggplot(pten1_proc_wt, aes(y=score, x=end, colour = end)) + geom_violin(draw_quantiles=c(0.5), data=subset(pten1_proc_wt, start== "R"), aes(group=end), scale = "width") + xlab("Amino acid") + ggtitle("Arganine variant abundance scores")+ geom_point(data=subset(pten1_proc_wt, start== "R"), aes(x=end, y=score), alpha = 0.75, position=jitter1) + scale_color_manual(values=twenty_color)
pten_n_spread1 <- ggplot(pten1_proc_wt, aes(y=score, x=factor(position), colour = end)) + geom_violin(draw_quantiles=c(0.5), data=subset(pten1_proc_wt, start== "N"), aes(group=factor(position)), scale = "width") + xlab("Position in PTEN") + ggtitle("Asparagine variant abundance scores")+ geom_point(data=subset(pten1_proc_wt, start== "N"), aes(x=factor(position), y=score), alpha = 0.85, position=jitter2) + scale_color_manual(values=twenty_color)
pten_n_aa <- ggplot(pten1_proc_wt, aes(y=score, x=end, colour = end)) + geom_violin(draw_quantiles=c(0.5), data=subset(pten1_proc_wt, start== "N"), aes(group=end), scale = "width") + xlab("Amino acid") + ggtitle("Asparagine variant abundance scores")+ geom_point(data=subset(pten1_proc_wt, start== "N"), aes(x=end, y=score), alpha = 0.75, position=jitter1) + scale_color_manual(values=twenty_color)
pten_d_spread1 <- ggplot(pten1_proc_wt, aes(y=score, x=factor(position), colour = end)) + geom_violin(draw_quantiles=c(0.5), data=subset(pten1_proc_wt, start== "D"), aes(group=factor(position)), scale = "width") + xlab("Position in PTEN") + ggtitle("Aspartic Acid variant abundance scores")+ geom_point(data=subset(pten1_proc_wt, start== "D"), aes(x=factor(position), y=score), alpha = 0.85, position=jitter2) + scale_color_manual(values=twenty_color)
pten_d_aa <- ggplot(pten1_proc_wt, aes(y=score, x=end, colour = end)) + geom_violin(draw_quantiles=c(0.5), data=subset(pten1_proc_wt, start== "D"), aes(group=end), scale = "width") + xlab("Amino acid") + ggtitle("Aspartic Acid variant abundance scores")+ geom_point(data=subset(pten1_proc_wt, start== "D"), aes(x=end, y=score), alpha = 0.75, position=jitter1) + scale_color_manual(values=twenty_color)
plot(pten_a_spread1)

plot(pten_a_aa)

plot(pten_r_spread1)

plot(pten_r_aa)

plot(pten_n_spread1)

plot(pten_n_aa)

plot(pten_d_spread1)

plot(pten_d_aa)

VAMP-seq abundance score density plots for PTEN (top) and TPMT (bottom) nonsense variants (blue dashed line), synonymous variants (red dashed line) and missense variants (filled, solid line). The missense variant densities are colored as gradients between the lowest 10% of abundance scores (blue), the WT abundance score (white) and abundance scores above WT (red).
#Identifying items in tail to investigate
pten1_nonsense <- subset(pten1_proc, class == "nonsense")
tpmt1_nonsense <- subset(tpmt1_proc, class == "nonsense")
pten1_synon <- subset(pten1_proc, class == "synonymous")
tpmt1_synon <- subset(tpmt1_proc, class == "synonymous")
pten1_no_missense <- subset(pten1_proc, class == "synonymous" | class == "nonsense")
ggplot(pten1_nonsense, aes(x=score)) + geom_histogram(binwidth=.01, colour="blue", fill="white")

#+ geom_density()
ggplot(pten1_synon, aes(x=score)) + geom_histogram(binwidth=.01, colour="red", fill="white")

ggplot(pten1_proc_wt, aes(x=score)) + geom_histogram(data=subset(pten1_proc_wt,class == "nonsense"), fill = "red", alpha = 0.5, binwidth=.01) + geom_histogram(data=subset(pten1_proc_wt,class == "synonymous"), fill = "blue", alpha = 0.5, binwidth=.01) + geom_histogram(data=subset(pten1_proc_wt,class == "missense"), fill = "green", alpha = 0.2, binwidth=.01)

ggplot(pten1_no_missense, aes(x=score)) + geom_histogram(data=subset(pten1_no_missense,class == "nonsense"), fill = "red", alpha = 0.5, binwidth=.01) + geom_histogram(data=subset(pten1_no_missense,class == "synonymous"), fill = "blue", alpha = 0.5, binwidth=.01)

ggplot(tpmt1_synon, aes(x=score)) + geom_histogram(binwidth=.01, colour="red", fill="white")

ggplot(tpmt1_nonsense, aes(x=score)) + geom_histogram(binwidth=.01, colour="blue", fill="white")

#0.55
nonsense_tail <- subset(pten1_nonsense, score > 0.6)
synon_tail <- subset(pten1_synon, score < 0.6)
nonsense_tail$secondary_struct <- ifelse(is.na(nonsense_tail$helix), "unknown",
ifelse(nonsense_tail$helix==1, "helix",
ifelse(nonsense_tail$sheet==1, "sheet",
ifelse(nonsense_tail$helix==0, "neither",
"unknown"))))
synon_tail$secondary_struct <- ifelse(is.na(synon_tail$helix), "unknown",
ifelse(synon_tail$helix==1, "helix",
ifelse(synon_tail$sheet==1, "sheet",
ifelse(synon_tail$helix==0, "neither",
"unknown"))))
#data[row,column]
n_tail <- nonsense_tail[,c(1,2,7,30,127)]
s_tail <- synon_tail[,c(1,2,7,30,127)]
n_tail$bp_pos <- (n_tail$position-1)*3
s_tail$bp_pos <- (s_tail$position-1)*3
n_tail
s_tail
#just in case there is a discernible pattern
s_tail_pos <- ggplot(s_tail, aes(x=position, y=score, colour=secondary_struct))+ geom_point(size=.3) + scale_x_continuous(minor_breaks = seq(0, 405, 5)) + scale_color_manual(values=c("#FF4848", "#00C853", "#5757FF", "#A9A9A9")) +ylab("VAMP-seq score")+xlab("Position in PTEN")+labs(colour="Secondary Structure")+ggtitle("PTEN synonymous variant tail scores in relation to protein structure") + geom_vline(xintercept=47, color="black", size=.1) + geom_vline(xintercept=78, color="black", size=.1) + geom_vline(xintercept=122.5, color="black", size=.1) + geom_vline(xintercept=140, color="black", size=.1) + geom_vline(xintercept=165, color="black", size=.1) + geom_vline(xintercept=194, color="black", size=.1) + geom_vline(xintercept=209, color="black", size=.1)
plot(s_tail_pos)

#help visualizing NMD rules
n_tail_pos <- ggplot(n_tail, aes(x=position, y=score, colour=secondary_struct))+ geom_point(size=.3) + scale_x_continuous(minor_breaks = seq(0, 405, 5)) + scale_color_manual(values=c("#FF4848", "#00C853", "#5757FF", "#A9A9A9")) +ylab("VAMP-seq score")+xlab("Position in PTEN")+labs(colour="Secondary Structure")+ggtitle("PTEN nonsense variant tail scores in relation to protein structure") + geom_vline(xintercept=47, color="black", size=.1) + geom_vline(xintercept=78, color="black", size=.1) + geom_vline(xintercept=122.5, color="black", size=.1) + geom_vline(xintercept=140, color="black", size=.1) + geom_vline(xintercept=165, color="black", size=.1) + geom_vline(xintercept=194, color="black", size=.1) + geom_vline(xintercept=209, color="black", size=.1)
plot(n_tail_pos)

#reversing data to fit tpmt1_data
rever <- function(df=tpmt_ruddle_data){df<-df[dim(df)[1]:1,]}
tpmt_ruddle_data_rev = rever(tpmt_ruddle_data)
#creating variant column, equiv to tpmt1_data's
tpmt_ruddle_data_rev$variant <- do.call(paste, c(tpmt_ruddle_data_rev[c(5,24,6)], sep=""))
#making both tables smaller
tpmt_essential <- tpmt_ruddle_data_rev[,c(2,3,4,5,6,17,19,24,27,28,29,30,31,32,33,34,35,76,77,78,137)]
tpmt1_proc_ess <- tpmt1_proc_wt[,c(1,2,3,5,6,7,30,32,80)]
#merging tables with variant name
tpmt_merge <- merge(tpmt1_proc_ess, tpmt_essential, by="variant")
#comparing abundance scores with various scores in dbNSFP (contains annotations of all potential non-synonymous single-nucleotide variants (nsSNVs) in the human genome)
tpmt_cor1 <- ggplot(tpmt_merge, aes(x=score, y=as.numeric(SIFT_score)))+ geom_point(alpha = 0.2) + xlab("VAMP-seq score")+ylab("SIFT score")+ggtitle("1")
tpmt_cor1.5 <- ggplot(tpmt_merge, aes(x=score, y=as.numeric(SIFT_converted_rankscore)))+ geom_point(alpha = 0.2) + xlab("VAMP-seq score")+ylab("SIFT converted rankscore")+ggtitle("1.5")
tpmt_cor5 <- ggplot(tpmt_merge, aes(x=score, y=CADD_raw_rankscore))+ geom_point(alpha = 0.2) + xlab("VAMP-seq score")+ylab("CADD raw rankscore")+ggtitle("5")
tpmt_cor2 <- ggplot(tpmt_merge, aes(x=score, y=as.numeric(Polyphen2_HDIV_score)))+ geom_point(alpha = 0.2) + xlab("VAMP-seq score")+ylab("Polyphen2 HDIV score")+ggtitle("2")
tpmt_cor3 <- ggplot(tpmt_merge, aes(x=score, y=as.numeric(Polyphen2_HVAR_score)))+ geom_point(alpha = 0.2) + xlab("VAMP-seq score")+ylab("Polyphen2 HVAR score")+ggtitle("3")
tpmt_cor2.5 <- ggplot(tpmt_merge, aes(x=score, y=as.numeric(Polyphen2_HDIV_rankscore)))+ geom_point(alpha = 0.2) + xlab("VAMP-seq score")+ylab("Polyphen2 HDIV rankscore")+ggtitle("2.5")
tpmt_cor3.5 <- ggplot(tpmt_merge, aes(x=score, y=as.numeric(Polyphen2_HVAR_rankscore)))+ geom_point(alpha = 0.2) + xlab("VAMP-seq score")+ylab("Polyphen2 HVAR rankscore")+ggtitle("3.5")
#CADD_phred not worth
#plot(tpmt_cor5)
#plot(tpmt_cor1)
#plot(tpmt_cor1.5)
plot(tpmt_cor2)

plot(tpmt_cor3)

plot(tpmt_cor2.5)

plot(tpmt_cor3.5)

TPMT_abun_CADD <- ggplot(tpmt_merge, aes(x=abundance_class, y=CADD_raw_rankscore)) + geom_violin(draw_quantiles = c( 0.5))+ylab("CADD raw rankscore")+xlab("Abundance Class")
plot(TPMT_abun_CADD)

TPMT_abun_SIFT_conv <- ggplot(tpmt_merge, aes(x=abundance_class, y=as.numeric(SIFT_converted_rankscore))) + geom_violin(draw_quantiles = c(0.5))+ylab("SIFT conv rankscore")+xlab("Abundance Class")
plot(TPMT_abun_SIFT_conv)

TPMT_abun_POLY <- ggplot(tpmt_merge, aes(x=abundance_class, y=as.numeric(Polyphen2_HDIV_rankscore))) + geom_violin(draw_quantiles = c( 0.5))+ylab("Polyphen2 HDIV rankscore")+xlab("Abundance Class")
plot(TPMT_abun_POLY)

TPMT_abun_POLY1 <- ggplot(tpmt_merge, aes(x=abundance_class, y=as.numeric(Polyphen2_HVAR_rankscore))) + geom_violin(draw_quantiles = c( 0.5))+ylab("Polyphen2 HVAR rankscore")+xlab("Abundance Class")
plot(TPMT_abun_POLY1)

Pred_abun_SIFT <- ggplot(tpmt_merge, aes(abundance_class)) + geom_bar(aes(fill = SIFT_pred)) + ggtitle("Abundance class vs SIFT prediction of Damaging or Tolerated")
plot(Pred_abun_SIFT)

trial_sep <- tpmt_merge[c(21,23,24,26)]
tpmt_merge_expand <- separate_rows(tpmt_merge, c("Polyphen2_HDIV_score", "Polyphen2_HDIV_pred", "Polyphen2_HVAR_score", "Polyphen2_HVAR_pred"))
Pred_abun_HVAR <- ggplot(tpmt_merge_expand, aes(abundance_class)) + geom_bar(aes(fill = Polyphen2_HVAR_pred)) + ggtitle("Abundance class vs Polyphen2 HVAR predictions") + labs(subtitle = "D: Probably Damaging, P: Possibly Damaging, B: Benign")
plot(Pred_abun_HVAR)

#creation of b-score text files for pymol use
pten_pymol <- summarySE(pten1_data, measurevar="score", groupvars="position", na.rm=TRUE)
NaNs produced
#score[404] is wt
write.table(pten_pymol$score[1:403], "pten_mean_scores_pymol.txt", sep="\n", row.names=F, col.names=F, na = "NaN")
tpmt_pymol <- summarySE(tpmt1_data, measurevar="score", groupvars="position", na.rm=TRUE)
NaNs produced
#score[404] is wt
write.table(tpmt_pymol$score[1:245], "tpmt_mean_scores_pymol.txt", sep="\n", row.names=F, col.names=F, na = "NaN")
LS0tCnRpdGxlOiAiUFRFTiBSIE5vdGVib29rIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCmBgYHtyIGdsb2JhbF9vcHRpb25zLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KGdncGxvdDIpCnJlcXVpcmUoZ3JpZEV4dHJhKQpsaWJyYXJ5KHJlc2hhcGUyKQpsaWJyYXJ5KHByYWNtYSkKbGlicmFyeShnZ2JlZXN3YXJtKQpsaWJyYXJ5KFJtaXNjKQpsaWJyYXJ5KGdyaWQpCmxpYnJhcnkoRUJJbWFnZSkKbGlicmFyeShnb29nbGVzaGVldHMpCmxpYnJhcnkodGlkeXIpCmxpYnJhcnkoZHBseXIpCmtuaXRyOjpvcHRzX2NodW5rJHNldChmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9MTIsIHdhcm5pbmc9RkFMU0UpCmBgYApNdWx0aXBsZXggYXNzZXNzbWVudCBvZiBwcm90ZWluIHZhcmlhbnQgYWJ1bmRhbmNlIGJ5IG1hc3NpdmVseSBwYXJhbGxlbCBzZXF1ZW5jaW5nClZBTVAtc2VxCi0gbXVsdGlwbGV4IGFzc2F5IHRoYXQgdXNlcyBmbHVvcmVzY2VudCByZXBvcnRlcnMgdG8gbWVhc3VyZSB0aGUgc3RlYWR5LXN0YXRlIGFidW5kYW5jZSBvZiBwcm90ZWluIHZhcmlhbnRzIGluIGN1bHR1cmVkIGh1bWFuIGNlbGxzIChlYWNoIGNlbGxleHByZXNzZXMgYSBzaW5nbGUgdmFyaWFudCBkaXJlY3RseSBmdXNlZCB0byBFR0ZQLi4udGhlIHN0YWJpbGl0eSBvZiB0aGUgdmFyaWFudCBkaWN0YXRlcyB0aGUgYWJ1bmRhbmNlIG9mIHRoZSBFR0ZQIGZ1c2lvbiBhbmQsIGFjY29yZGluZ2x5LCB0aGUgZ3JlZW4gZmx1b3Jlc2NlbmNlIHNpZ25hbCBvZiB0aGUgY2VsbCkKLSB1c2VkIHRvIGFzc2VzcyBQVEVOIGFuZCBUUE1UIHZhcmlhbnRzIApgYGB7ciBpbmNsdWRlPUZBTFNFfQpwYXIocGNoPTIwLCBjZXg9LjYpCnB0ZW4xX2RhdGEgPC0gcmVhZC5kZWxpbSgnfi9sZWtsYWIvbGVrbGFiL3B0ZW4xLnR4dCcpCnB0ZW4xX3Byb2MgPC0gcHRlbjFfZGF0YVshaXMubmEocHRlbjFfZGF0YSRhYnVuZGFuY2VfY2xhc3MpLF0KZGQgPC0gZGF0YS5mcmFtZShwdGVuMV9wcm9jJGFidW5kYW5jZV9jbGFzcyxwdGVuMV9wcm9jJHNjb3JlKQpjb2xuYW1lcyhkZCkgPC0gYygiYWJ1bmRhbmNlX2NsYXNzIiwgInNjb3JlIikKdHBtdDFfZGF0YSA8LSByZWFkLmRlbGltKCd+L2xla2xhYi9sZWtsYWIvdHBtdF9zdXBwbF8yLnR4dCcpCnRwbXQxX3Byb2MgPC0gdHBtdDFfZGF0YVshaXMubmEodHBtdDFfZGF0YSRhYnVuZGFuY2VfY2xhc3MpLF0KZWUgPC0gZGF0YS5mcmFtZSh0cG10MV9wcm9jJGFidW5kYW5jZV9jbGFzcyx0cG10MV9wcm9jJHNjb3JlKQpjb2xuYW1lcyhlZSkgPC0gYygiYWJ1bmRhbmNlX2NsYXNzIiwgInNjb3JlIikKZGQkcHJvdGVpbiA8LSByZXAoIlBURU4iLCBucm93KGRkKSkKZWUkcHJvdGVpbiA8LSByZXAoIlRQTVQiLCBucm93KGVlKSkKZmYgPSBkYXRhLmZyYW1lKHJiaW5kKGRkLCBlZSkpCmJicHAgPSBib3hwbG90KHNjb3JlfnByb3RlaW4rYWJ1bmRhbmNlX2NsYXNzLCBkYXRhID0gZmYsIGF0ID0gYygxLCAxLjgsIDMsIDMuOCwgNSwgNS44LCA3LjIsIDgpLCB4YXh0PSduJywgY29sID0gYygnd2hpdGUnLCAnZ3JheScpKQpheGlzKHNpZGU9MSwgYXQ9YygxLjQsIDMuNCwgNS40LCA3LjYpLCBsYWJlbHM9YygnbG93JywgJ3Bvc3NpYmx5IGxvdycsICdwb3NzaWJseVxuIHd0LWxpa2UnLCAnd3QtbGlrZScpKQp0aXRsZSgnVkFNUC1zZXEgc2NvcmVzIG9mIFBURU4gYW5kIFRQTVQgVmFyaWFudHNcbmFuZCBhYnVuZGFuY2UgY2xhc3MnKQoKCiNwbG90KHggPSBwdGVuMV9wcm9jJGFidW5kYW5jZV9jbGFzcywgeSA9IHB0ZW4xX3Byb2Mkc2NvcmUsdHlwZT0ncCcsIG1haW4gPSAiUFRFTiIsIHhsYWIgPSAiQWJ1bmRhbmNlIiwgeWxhYiA9ICJWQU1QLXNlcSBzY29yZSIsIGNvbD0iIzc0QUJENiIpCiNwb2ludHMoeCA9IHRwbXQxX3Byb2MkYWJ1bmRhbmNlX2NsYXNzLCB5ID0gdHBtdDFfcHJvYyRzY29yZSwgdHlwZT0ncCcsIGNvbCA9ICIjQURERkFEIikKYGBgCmBgYHtyIGluY2x1ZGU9RkFMU0V9CgojIGQgPC0gcmVhZC50YWJsZSh0ZXh0ID0gImNvbF9hIGNvbF9iIAojICAgICAgICAgICAgICAgICAgICAgICAgIGFhICAgIDEKIyAgICAgICAgICAgICAgICAgICAgICAgICBiYSAgICAxLjI1CiMgICAgICAgICAgICAgICAgICAgICAgICAgYmEgICAgMQojICAgICAgICAgICAgICAgICAgICAgICAgIGJhICAgIDEuMjUKIyAgICAgICAgICAgICAgICAgICAgICAgICBjYSAgICAxLjMKIyAgICAgICAgICAgICAgICAgICAgICAgICBjYSAgICAxLjI1CiMgICAgICAgICAgICAgICAgICAgICAgICAgZGEgICAgMS41CiMgICAgICAgICAgICAgICAgICAgICAgICAgZGEgICAgMS4yNQojICAgICAgICAgICAgICAgICAgICAgICAgIGFhICAgIDEuNwojICAgICAgICAgICAgICAgICAgICAgICAgIGNhICAgIDEuMjUKIyAgICAgICAgICAgICAgICAgICAgICAgICBiYSAgICAxLjIKIyAgICAgICAgICAgICAgICAgICAgICAgICBkYSAgICAxLjI1CiMgICAgICAgICAgICAgICAgICAgICAgICAgYWEgICAgMS40CiMgICAgICAgICAgICAgICAgICAgICAgICAgYWEgICAgMS4yNQojICAgICAgICAgICAgICAgICAgICAgICAgIGNhICAgIDEuMQojICAgICAgICAgICAgICAgICAgICAgICAgIGFhICAgIDEuMjUiLCAKIyAgICAgICAgICAgICAgICAgaGVhZGVyID0gVFJVRSwpCiMgZSA8LSByZWFkLnRhYmxlKHRleHQgPSAiY29sX2EgY29sX2IgCiMgICAgICAgICAgICAgICAgICAgICAgICAgYWEgICAgMS42CiMgICAgICAgICAgICAgICAgICAgICAgICAgYWEgICAgMS41NQojICAgICAgICAgICAgICAgICAgICAgICAgIGJhICAgIDEuMgojICAgICAgICAgICAgICAgICAgICAgICAgIGJhICAgIDEuNDUKIyAgICAgICAgICAgICAgICAgICAgICAgICBjYSAgICAxLjgKIyAgICAgICAgICAgICAgICAgICAgICAgICBjYSAgICAxLjU1CiMgICAgICAgICAgICAgICAgICAgICAgICAgZGEgICAgMS41CiMgICAgICAgICAgICAgICAgICAgICAgICAgZGEgICAgMS4zNQojICAgICAgICAgICAgICAgICAgICAgICAgIGFhICAgIDEuOQojICAgICAgICAgICAgICAgICAgICAgICAgIGNhICAgIDEuNzUKIyAgICAgICAgICAgICAgICAgICAgICAgICBiYSAgICAxLjI1CiMgICAgICAgICAgICAgICAgICAgICAgICAgZGEgICAgMS41NQojICAgICAgICAgICAgICAgICAgICAgICAgIGFhICAgIDEuNDUKIyAgICAgICAgICAgICAgICAgICAgICAgICBhYSAgICAxLjUKIyAgICAgICAgICAgICAgICAgICAgICAgICBjYSAgICAxLjMKIyAgICAgICAgICAgICAgICAgICAgICAgICBhYSAgICAxLjc1IiwgCiMgICAgICAgICAgICAgICAgIGhlYWRlciA9IFRSVUUsKQojIGQkbGFiZWwgPC0gcmVwKDEsIG5yb3coZCkpCiMgZSRsYWJlbCA8LSByZXAoMiwgbnJvdyhlKSkKIyBmID0gZGF0YS5mcmFtZShyYmluZChkLCBlKSkKIyAjI2YkY29sX2EgPSBwb2xsdXRhbnQKIyAjI2YkbGFiZWwgPSBsb2NhdGlvbgojIGJwID0gYm94cGxvdChjb2xfYn5sYWJlbCtjb2xfYSwgZGF0YSA9IGYsIGF0ID0gYygxLCAxLjgsIDMsIDMuOCwgNSwgNS44LCA3LjIsIDgpLCB4YXh0PSduJywgeWxpbSA9IGMoLjksIDEuOSksIGNvbCA9IGMoJ3doaXRlJywgJ2dyYXknKSkKIyBheGlzKHNpZGU9MSwgYXQ9YygxLjQsIDMuNCwgNS40LCA3LjYpLCBsYWJlbHM9YygnYWEnLCAnYmEnLCAnY2EnLCAnZGEnKSwgdGl0bGUoJ3ByYWN0aWNlJykpCmBgYApgYGB7cn0KI3Bsb3RzIFZBTVAtc2VxIHNjb3JlIHZzIGFidW5kYW5jZV9jbGFzcwoKVkFNUF9hYnVuZGFuY2UgPC0gZ2dwbG90KGZmLCBhZXMoeD1hYnVuZGFuY2VfY2xhc3MsIHk9c2NvcmUsIGZpbGw9cHJvdGVpbikpICsgZ2VvbV92aW9saW4oZHJhd19xdWFudGlsZXMgPSAwLjUpK3lsYWIoIlZBTVAtc2VxIHNjb3JlIikreGxhYigiQWJ1bmRhbmNlIENsYXNzIikrdGhlbWUobGVnZW5kLnRpdGxlPWVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiZ3JleSIpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJncmV5IikpK2dndGl0bGUoIlZBTVAtc2VxIHNjb3JlcyBmb3IgZWFjaCBhYnVuZGFuY2UgY2xhc3NpZmljYXRpb24iKStnZW9tX3BvaW50KGRhdGE9ZGF0YS5mcmFtZSh4PSJ3dC1saWtlIiwgeT0xLCBwcm90ZWluID0gIlBURU4iKSwgYWVzKHgseSksIGNvbG91cj0iYmxhY2siLCBzaXplPTEuNSwgc2hvdy5sZWdlbmQ9RkFMU0UpK2Fubm90YXRlKCJ0ZXh0IiwgeCA9ICJ3dC1saWtlIiwgeT0xLjA5LCBsYWJlbCA9ICJXVCIsY29sb3VyPSAiYmxhY2siLCBzaXplID0gNCkgKyBzY2FsZV95X2NvbnRpbnVvdXMobWlub3JfYnJlYWtzID0gc2VxKC0yLCAyLCAuMjUpKSt0aGVtZV9idygpCnBsb3QoVkFNUF9hYnVuZGFuY2UpCmBgYApgYGB7ciBpbmNsdWRlPUZBTFNFfQojcGxvdHMgaGVsaXggdnMgc2NvcmUgZm9yIFBURU4KI2dncGxvdChwdGVuMV9kYXRhLCBhZXMoeD1hcy5mYWN0b3IoaGVsaXgpLCB5PXNjb3JlKSkgKyBnZW9tX2JveHBsb3QoKSt5bGFiKCJWQU1QLXNlcSBzY29yZSIpCmBgYApgYGB7ciBpbmNsdWRlPUZBTFNFfQojY29tYmluaW5nIHB0ZW4xX2RhdGEgYW5kIHRwbXQxX2RhdGEgaW50byBvbmUgbGFyZ2UgZGF0YSBmcmFtZSwgZGlmZmVyZW50aWF0ZSBiZXR3ZWVuIHRoZSB0d28gdy8gY29sdW1uICdwcm90ZWluJyB3aGljaCBzcGVjaWZpZXMgJ1BURU4nIG9yICdUUE1UJwpwdGVuMV9kYXRhJHByb3RlaW4gPC0gcmVwKCJQVEVOIiwgbnJvdyhwdGVuMV9kYXRhKSkKdHBtdDFfZGF0YSRwcm90ZWluIDwtIHJlcCgiVFBNVCIsIG5yb3codHBtdDFfZGF0YSkpCmNvbW1vbl9jb2xzIDwtIGludGVyc2VjdChjb2xuYW1lcyhwdGVuMV9kYXRhKSwgY29sbmFtZXModHBtdDFfZGF0YSkpCmNvbWJfZGF0YSA9IHJiaW5kKHN1YnNldChwdGVuMV9kYXRhLCBzZWxlY3QgPSBjb21tb25fY29scyksIHN1YnNldCh0cG10MV9kYXRhLCBzZWxlY3QgPSBjb21tb25fY29scykpCgojcGxvdHMgaGVsaXggdnMgc2NvcmUgZm9yIFBURU4gYW5kIFRQTVQgc2lkZSBieSBzaWRlCiNubyBOQQoKY29tYl9kYXRhX2hlbGl4IDwtIGNvbWJfZGF0YVshaXMubmEoY29tYl9kYXRhJGhlbGl4KSxdCiNjaGVjayB0byBzZWUgd2hlcmUgMzc1OSByb3dzIHdlbnQgb2ZmIHRvCmNrIDwtIGNvbWJfZGF0YV9oZWxpeFshaXMubmEoY29tYl9kYXRhX2hlbGl4JGFidW5kYW5jZV9jbGFzcyksXQpjb21iX2RhdGFfc2hlZXQgPC0gY29tYl9kYXRhWyFpcy5uYShjb21iX2RhdGEkc2hlZXQpLF0KY2sxIDwtIGNvbWJfZGF0YV9zaGVldFshaXMubmEoY29tYl9kYXRhX3NoZWV0JGFidW5kYW5jZV9jbGFzcyksXQoKaF9wbG90IDwtIGdncGxvdChjaywgYWVzKHg9YXMuZmFjdG9yKGhlbGl4KSwgeT1zY29yZSwgZmlsbD1wcm90ZWluKSkgKyBnZW9tX3Zpb2xpbihkYXRhPXN1YnNldChjaywgaGVsaXg9PTEpLCBkcmF3X3F1YW50aWxlcyA9IGMoMC41KSkgKyBndWlkZXMoZmlsbD1GQUxTRSkgKyB4bGFiKCJBbHBoYSBIZWxpeCIpICsgeWxhYigiVkFNUC1zZXEgc2NvcmUiKSArIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpKSArIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC0uNywgMi4wMykpCgpzX3Bsb3QgPC0gZ2dwbG90KGNrMSwgYWVzKHg9YXMuZmFjdG9yKHNoZWV0KSwgeT1zY29yZSwgZmlsbD1wcm90ZWluKSkgKyBnZW9tX3Zpb2xpbihkYXRhPXN1YnNldChjazEsIHNoZWV0PT0xKSwgZHJhd19xdWFudGlsZXMgPSBjKDAuNSkpICsgIHRoZW1lKGF4aXMudGl0bGUueSA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpKSArIHhsYWIoIkJldGEgU2hlZXQiKSArIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC0uNywgMi4wMykpICsgZ3VpZGVzKGZpbGw9RkFMU0UpIAoKbl9wbG90IDwtIGdncGxvdChjaywgYWVzKHg9YXMuZmFjdG9yKGhlbGl4KSwgeT1zY29yZSwgZmlsbD1wcm90ZWluKSkgKyBnZW9tX3Zpb2xpbihkYXRhPXN1YnNldChjaywgaGVsaXg9PTAgJiBzaGVldD09MCksIGRyYXdfcXVhbnRpbGVzID0gYyggMC41KSkgKyB0aGVtZSggYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC5qdXN0aWZpY2F0aW9uPWMoMSwwKSwgbGVnZW5kLnBvc2l0aW9uPWMoLjQ5LC43NSksIGxlZ2VuZC50aXRsZT1lbGVtZW50X2JsYW5rKCksIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTApKSArIHhsYWIoIk90aGVyIikgKyBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtLjcsIDIuMDMpKQoKI3B1dCB0aGUgcGxvdHMgc2lkZSBieSBzaWRlCmNvbWJpbmVkIDwtIGdyaWQuYXJyYW5nZShoX3Bsb3QsIHNfcGxvdCwgbl9wbG90LCBuY29sPTMsIHRvcCA9ICJWYXJpYW50IHNjb3JlcyBpbiByZWxhdGlvbiB0byBwb3NpdGlvbiBpbiBwcm90ZWluIikKIyMjIyMjIyMjIyMjIyMKIyNzYXZlIGFzIHBkZgoKIyBwZGYoInZpb2xpbl9WYXJpYW50X3Njb3Jlc192cy5wZGYiKQojIHBsb3QoY29tYmluZWQpCiMgcGxvdChWQU1QX2FidW5kYW5jZSkKIyBkZXYub2ZmKCkKIyMjIyMjIyMjIyMjIyMKI3dvcmtzIHRvIHNhdmUgc2luZ2xlCiNnZ3NhdmUoIlZhcmlhbnRfc2NvcmVzX3Byb3RlaW5fcG9zaXRpb24ucGRmIiwgcGxvdCA9IGNvbWJpbmVkLCBkZXZpY2UgPSAicGRmIiwgcGF0aCA9ICIvVXNlcnMvZ28yYWx5c3NhL0Rlc2t0b3AvIiwgc2NhbGUgPSAyLjYsIGRwaSA9ICJyZXRpbmEiKQoKYGBgCgpgYGB7cn0KIyBncmFwaCBWQU1QLXNlcSBzY29yZXMgcmVsYXRpdmUgdG8gdmFyaWFudCBwb3NpdGlvbiBpbiBwcm90ZWluCiNwdGVuCnB0ZW4xX3Byb2Nfd3QgPC0gcHRlbjFfcHJvY1shaXMubmEocHRlbjFfcHJvYyRwb3NpdGlvbiksXQpwdGVuMV9wcm9jX3d0JHNlY29uZGFyeV9zdHJ1Y3QgPC0gaWZlbHNlKGlzLm5hKHB0ZW4xX3Byb2Nfd3QkaGVsaXgpLCAidW5rbm93biIsCiAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShwdGVuMV9wcm9jX3d0JGhlbGl4PT0xLCAiaGVsaXgiLAogICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UocHRlbjFfcHJvY193dCRzaGVldD09MSwgInNoZWV0IiwKICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHB0ZW4xX3Byb2Nfd3QkaGVsaXg9PTAsICJuZWl0aGVyIiwKICAgICAgICAgICAgICAgICAgICAgICAgInVua25vd24iKSkpKQpwdGVuX3BvcyA8LSBnZ3Bsb3QocHRlbjFfcHJvY193dCwgYWVzKHg9cG9zaXRpb24sIHk9c2NvcmUsIGNvbG91cj1zZWNvbmRhcnlfc3RydWN0KSkrIGdlb21fcG9pbnQoc2l6ZT0uMykgKyBzY2FsZV94X2NvbnRpbnVvdXMobWlub3JfYnJlYWtzID0gc2VxKDAsIDQyMCwgNSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jKCIjRkY0ODQ4IiwgIiMwMEM4NTMiLCAiIzU3NTdGRiIsICIjQTlBOUE5IikpICt5bGFiKCJWQU1QLXNlcSBzY29yZSIpK3hsYWIoIlBvc2l0aW9uIGluIFBURU4iKStsYWJzKGNvbG91cj0iU2Vjb25kYXJ5IFN0cnVjdHVyZSIpK2dndGl0bGUoIlBURU4gc2NvcmVzIGluIHJlbGF0aW9uIHRvIHByb3RlaW4gc3RydWN0dXJlIikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9MjcsIGNvbG9yPSJibGFjayIsIHNpemU9LjEpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0PTU1LCBjb2xvcj0iYmxhY2siLCBzaXplPS4xKSArIGdlb21fdmxpbmUoeGludGVyY2VwdD03MCwgY29sb3I9ImJsYWNrIiwgc2l6ZT0uMSkgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9ODUsIGNvbG9yPSJibGFjayIsIHNpemU9LjEpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0PTE2NC41LCBjb2xvcj0iYmxhY2siLCBzaXplPS4xKSArIGdlb21fdmxpbmUoeGludGVyY2VwdD0yMTIsIGNvbG9yPSJibGFjayIsIHNpemU9LjEpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0PTI2Ny41LCBjb2xvcj0iYmxhY2siLCBzaXplPS4xKSArIGdlb21fdmxpbmUoeGludGVyY2VwdD0zNDMuNSwgY29sb3I9ImJsYWNrIiwgc2l6ZT0uMSkrdGhlbWVfYncoKQoKcHRlbl9oeWRybyA8LSBnZ3Bsb3QocHRlbjFfcHJvY193dCwgYWVzKHg9cG9zaXRpb24sIHk9c2NvcmUsIGNvbG91cj0oaHlkcm8yLWh5ZHJvMSkpKSsgZ2VvbV9wb2ludChzaXplPS4zLCBhbHBoYSA9IDAuMykgKyBzY2FsZV94X2NvbnRpbnVvdXMobWlub3JfYnJlYWtzID0gc2VxKDAsIDQyMCwgNSkpICsgeWxhYigiVkFNUC1zZXEgc2NvcmUiKSt4bGFiKCJQb3NpdGlvbiBpbiBQVEVOIikrbGFicyhjb2xvdXI9Ikh5ZHJvcGhvYmljaXR5IikrZ2d0aXRsZSgiUFRFTiBzY29yZXMgaW4gcmVsYXRpb24gdG8gY2hhbmdlIGluIGh5ZHJvcGhvYmljaXR5IikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9MjcsIGNvbG9yPSJibGFjayIsIHNpemU9LjEpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0PTU1LCBjb2xvcj0iYmxhY2siLCBzaXplPS4xKSArIGdlb21fdmxpbmUoeGludGVyY2VwdD03MCwgY29sb3I9ImJsYWNrIiwgc2l6ZT0uMSkgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9ODUsIGNvbG9yPSJibGFjayIsIHNpemU9LjEpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0PTE2NC41LCBjb2xvcj0iYmxhY2siLCBzaXplPS4xKSArIGdlb21fdmxpbmUoeGludGVyY2VwdD0yMTIsIGNvbG9yPSJibGFjayIsIHNpemU9LjEpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0PTI2Ny41LCBjb2xvcj0iYmxhY2siLCBzaXplPS4xKSArIGdlb21fdmxpbmUoeGludGVyY2VwdD0zNDMuNSwgY29sb3I9ImJsYWNrIiwgc2l6ZT0uMSkKCgojdHBtdAp0cG10MV9wcm9jX3d0IDwtIHRwbXQxX3Byb2NbIWlzLm5hKHRwbXQxX3Byb2MkcG9zaXRpb24pLF0KdHBtdDFfcHJvY193dCRzZWNvbmRhcnlfc3RydWN0IDwtIGlmZWxzZShpcy5uYSh0cG10MV9wcm9jX3d0JGhlbGl4KSwgInVua25vd24iLAogICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UodHBtdDFfcHJvY193dCRoZWxpeD09MSwgImhlbGl4IiwKICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHRwbXQxX3Byb2Nfd3Qkc2hlZXQ9PTEsICJzaGVldCIsCiAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh0cG10MV9wcm9jX3d0JGhlbGl4PT0wLCAibmVpdGhlciIsCiAgICAgICAgICAgICAgICAgICAgICAgICJ1bmtub3duIikpKSkKdHBtdF9wb3MgPC0gZ2dwbG90KHRwbXQxX3Byb2Nfd3QsIGFlcyh4PXBvc2l0aW9uLCB5PXNjb3JlLCBjb2xvdXI9c2Vjb25kYXJ5X3N0cnVjdCkpKyBnZW9tX3BvaW50KHNpemU9LjMpICsgc2NhbGVfeF9jb250aW51b3VzKG1pbm9yX2JyZWFrcyA9IHNlcSgwLCA0MDUsIDUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9YygiI0ZGNDg0OCIsICIjMDBDODUzIiwgIiM1NzU3RkYiLCAiI0E5QTlBOSIpKSAreWxhYigiVkFNUC1zZXEgc2NvcmUiKSt4bGFiKCJQb3NpdGlvbiBpbiBUUE1UIikrbGFicyhjb2xvdXI9IlNlY29uZGFyeSBTdHJ1Y3R1cmUiKStnZ3RpdGxlKCJUUE1UIHNjb3JlcyBpbiByZWxhdGlvbiB0byBwcm90ZWluIHN0cnVjdHVyZSIpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0PTQ3LCBjb2xvcj0iYmxhY2siLCBzaXplPS4xKSArIGdlb21fdmxpbmUoeGludGVyY2VwdD03OCwgY29sb3I9ImJsYWNrIiwgc2l6ZT0uMSkgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9MTIyLjUsIGNvbG9yPSJibGFjayIsIHNpemU9LjEpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0PTE0MCwgY29sb3I9ImJsYWNrIiwgc2l6ZT0uMSkgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9MTY1LCBjb2xvcj0iYmxhY2siLCBzaXplPS4xKSArIGdlb21fdmxpbmUoeGludGVyY2VwdD0xOTQsIGNvbG9yPSJibGFjayIsIHNpemU9LjEpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0PTIwOSwgY29sb3I9ImJsYWNrIiwgc2l6ZT0uMSkrdGhlbWVfYncoKQoKdHBtdF9jb2xvcnMgPC0gdHBtdDFfcHJvY193dAojW29yZGVyKHBvc2l0aW9uLCB2YXJpYW50KSxdCnRwbXRfY29sb3JzJGZhY3QgPC0gcmVwKDEwLCBucm93KHRwbXRfY29sb3JzKSkKdGVtcCA8LSAxCmZvcihpIGluIDE6KGxlbmd0aCh0cG10X2NvbG9ycyRmYWN0KS0xKSkgewogIGlmICh0cG10X2NvbG9ycyRzZWNvbmRhcnlfc3RydWN0W2ldICE9IHRwbXRfY29sb3JzJHNlY29uZGFyeV9zdHJ1Y3RbaSsxXSkgewogICAgdHBtdF9jb2xvcnMkZmFjdFtpXSA8LSB0ZW1wCiAgICB0ZW1wIDwtIHRlbXAgKyAxCiAgfSBlbHNlIHsKICB0cG10X2NvbG9ycyRmYWN0W2ldIDwtIHRlbXAKICB9Cn0KdHBtdF9jb2xvcnMkZmFjdFtsZW5ndGgodHBtdF9jb2xvcnMkZmFjdCldIDwtIHRlbXAKCiMgY2MgPC0gMAojIGZvcihpIGluIDE6KGxlbmd0aCh0cG10X2NvbG9ycyRmYWN0KS0xKSkgewojICAgaWYgKHRwbXRfY29sb3JzJGZhY3RbaV0gIT0gdHBtdF9jb2xvcnMkZmFjdFtpKzFdKSB7CiMgICAgIHByaW50KGNjKQojICAgICBjYyA8LSAwCiMgICB9IGVsc2UgewojICAgICBjYyA8LSBjYyArIDEKIyAgIH0KIyB9Cgp0cG10X3Bvc192cCA8LSBnZ3Bsb3QodHBtdF9jb2xvcnMsIGFlcyh4PXBvc2l0aW9uLCB5PXNjb3JlKSkrIGdlb21fdmlvbGluKGRhdGE9dHBtdF9jb2xvcnNbYygxOjI3ODMsIDI3OTg6NDAwMCksXSwgYWVzKGZpbGw9YXMuY2hhcmFjdGVyKGZhY3QpLCBjb2xvdXIgPSBmYWN0b3IoVFJVRSkpLCBkcmF3X3F1YW50aWxlcyA9IGMoMC41KSwgc2NhbGUgPSAid2lkdGgiKSArIApzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiMSIgPSAiI0E5QTlBOSIsICIyIiA9ICIjMDBDODUzIiwgIjMiID0gIiNGRjQ4NDgiLCAiNCIgPSAiIzAwQzg1MyIsIjUiID0gIiNGRjQ4NDgiLCAiNiIgPSAiIzAwQzg1MyIsIjciID0gIiM1NzU3RkYiLCAiOCIgPSAiIzAwQzg1MyIsIjkiID0gIiNGRjQ4NDgiLCIxMCIgPSAiIzAwQzg1MyIsIjExIiA9ICIjNTc1N0ZGIiwgIjEyIiA9ICIjMDBDODUzIiwiMTMiID0gIiNGRjQ4NDgiLCAiMTQiID0gIiMwMEM4NTMiLCAiMTUiID0gIiM1NzU3RkYiLCAiMTYiID0gIiMwMEM4NTMiLCAiMTciID0gIiM1NzU3RkYiLCAiMTgiID0gIiMwMEM4NTMiLCAiMTkiID0gIiM1NzU3RkYiLCAiMjAiID0gIiMwMEM4NTMiLCAiMjEiID0gIiM1NzU3RkYiLCAiMjIiID0gIiMwMEM4NTMiLCAiMjMiID0gIiNGRjQ4NDgiLCAiMjQiID0gIiM1NzU3RkYiLCAiMjUiID0gIiMwMEM4NTMiLCAiMjYiID0gIiNGRjQ4NDgiLCAiMjciID0gIiMwMEM4NTMiLCAiMjgiID0gIiM1NzU3RkYiLCAiMjkiID0gIiMwMEM4NTMiLCAiMzAiID0gIiM1NzU3RkYiLCAiMzEiID0gIiMwMEM4NTMiKSkgKyBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoImJsYWNrIikpICsgc2NhbGVfeF9jb250aW51b3VzKG1pbm9yX2JyZWFrcyA9IHNlcSgwLCA0MDUsIDUpKSArIHlsYWIoIlZBTVAtc2VxIHNjb3JlIikreGxhYigiUG9zaXRpb24gaW4gVFBNVCIpK2xhYnMoY29sb3VyPSJTZWNvbmRhcnkgU3RydWN0dXJlIikrZ2d0aXRsZSgiVFBNVCBzY29yZXMgaW4gcmVsYXRpb24gdG8gcHJvdGVpbiBzdHJ1Y3R1cmUiKSArIGdlb21fdmxpbmUoeGludGVyY2VwdD00NywgY29sb3I9ImJsYWNrIiwgc2l6ZT0uMSkgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9NzgsIGNvbG9yPSJibGFjayIsIHNpemU9LjEpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0PTEyMi41LCBjb2xvcj0iYmxhY2siLCBzaXplPS4xKSArIGdlb21fdmxpbmUoeGludGVyY2VwdD0xNDAsIGNvbG9yPSJibGFjayIsIHNpemU9LjEpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0PTE2NSwgY29sb3I9ImJsYWNrIiwgc2l6ZT0uMSkgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9MTk0LCBjb2xvcj0iYmxhY2siLCBzaXplPS4xKSArIGdlb21fdmxpbmUoeGludGVyY2VwdD0yMDksIGNvbG9yPSJibGFjayIsIHNpemU9LjEpCgoKcHRlbl9oeWRybzEgPC0gZ2dwbG90KHB0ZW4xX3Byb2Nfd3QsIGFlcyh5PXNjb3JlLCB4PShoeWRybzItaHlkcm8xKSkpKyBnZW9tX3BvaW50KHNpemU9MC41LCBhbHBoYSA9IDAuMykgKyB5bGFiKCJIeWRyb3Bob2JpY2l0eSIpK3hsYWIoIlZBTVAtc2VxIHNjb3JlIikrZ2d0aXRsZSgiUFRFTiBzY29yZXMgaW4gcmVsYXRpb24gdG8gY2hhbmdlIGluIGh5ZHJvcGhvYmljaXR5IikKCnB0ZW5fYWFfc3ByZWFkIDwtIGdncGxvdChwdGVuMV9wcm9jX3d0WzI6Mjg4LF0sIGFlcyh5PXNjb3JlLCB4PXN0YXJ0KSkgKyBnZW9tX3Zpb2xpbihkcmF3X3F1YW50aWxlcz1jKDAuNSkpCnB0ZW5fYWFfc3ByZWFkMSA8LSBnZ3Bsb3QocHRlbjFfcHJvY193dFsyOjI4OCxdLCBhZXMoeT1zY29yZSwgeD1zdGFydCkpICsgZ2VvbV9wb2ludChzaXplID0gMC41KQoKCnBsb3QocHRlbl9wb3MpCnBsb3QodHBtdF9wb3MpCgojcGxvdCh0cG10X3Bvc192cCkKI3Bsb3QocHRlbl9oeWRybykKI3Bsb3QocHRlbl9oeWRybzEpCiNwbG90KHB0ZW5fYWFfc3ByZWFkKQojcGxvdChwdGVuX2FhX3NwcmVhZDEpCmBgYApgYGB7cn0KIyBncmFwaCBWQU1QLXNlcSBzY29yZXMgcmVsYXRpdmUgdG8gdmFyaWFudCBwb3NpdGlvbiBpbiBwcm90ZWluCiNwdGVuCnB0ZW4xX2hib25kIDwtIHB0ZW4xX3Byb2NbIWlzLm5hKHB0ZW4xX3Byb2MkaGJvbmRfc3VtKSxdCnB0ZW4xX2hib25kJHNlY29uZGFyeV9zdHJ1Y3QgPC0gaWZlbHNlKGlzLm5hKHB0ZW4xX2hib25kJGhlbGl4KSwgInVua25vd24iLAogICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UocHRlbjFfaGJvbmQkaGVsaXg9PTEsICJoZWxpeCIsCiAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShwdGVuMV9oYm9uZCRzaGVldD09MSwgInNoZWV0IiwKICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHB0ZW4xX2hib25kJGhlbGl4PT0wLCAibmVpdGhlciIsCiAgICAgICAgICAgICAgICAgICAgICAgICJ1bmtub3duIikpKSkKcHRlbl9wbG90X2hib25kIDwtIGdncGxvdChwdGVuMV9oYm9uZCwgYWVzKHg9aGJvbmRfc3VtLCB5PXNjb3JlLCBjb2xvdXI9c2Vjb25kYXJ5X3N0cnVjdCkpKyBnZW9tX3BvaW50KGFscGhhPTAuNCkgKyB5bGFiKCJWQU1QLXNlcSBzY29yZSIpK3hsYWIoIkRTU1AgU3VtIG9mIGh5ZHJvZ2VuIGJvbmRzIikrZ2d0aXRsZSgiUFRFTiBzY29yZXMgaW4gcmVsYXRpb24gdG8gaHlkcm9nZW4gYm9uZGluZyIpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jKCIjRkY0ODQ4IiwgIiM2OTY5NjkiLCAiIzU3NTdGRiIpKSArIGxhYnMoY29sb3VyPSJTZWNvbmRhcnkgU3RydWN0dXJlIikKcGxvdChwdGVuX3Bsb3RfaGJvbmQpCgpwdGVuX3Bsb3RfaGJvbmQxIDwtIGdncGxvdChwdGVuMV9oYm9uZCwgYWVzKHg9aGJvbmRfc3VtLCB5PXNjb3JlKSkrIGdlb21fcG9pbnQoYWxwaGEgPSAwLjIpICsgeWxhYigiVkFNUC1zZXEgc2NvcmUiKSt4bGFiKCJEU1NQIFN1bSBvZiBoeWRyb2dlbiBib25kcyIpK2dndGl0bGUoIlBURU4gc2NvcmVzIGluIHJlbGF0aW9uIHRvIGh5ZHJvZ2VuIGJvbmRpbmciKQoKIyB3YXMgaW4gYWVzLCBnZ3Bsb3QgZnVuY3Rpb24gY2FsbCAtLS0+IGNvbG91cj1zZWNvbmRhcnlfc3RydWN0CiNzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoIiNGRjQ4NDgiLCAiIzAwQzg1MyIsICIjNTc1N0ZGIiwgIiNBOUE5QTkiKSkgKyBsYWJzKGNvbG91cj0iU2Vjb25kYXJ5IFN0cnVjdHVyZSIpKwoKcGxvdChwdGVuX3Bsb3RfaGJvbmQxKQojbGVzcyBoeWRyb2dlbiBib25kcyB+IGhpZ2hlciBhYnVuZGFuY2UKYGBgCmBgYHtyfQojVFBNVAp0cG10X3N1bSA8LSBzdW1tYXJ5U0UodHBtdDFfcHJvY193dCwgbWVhc3VyZXZhcj0ic2NvcmUiLCBncm91cHZhcnM9InBvc2l0aW9uIikKI2hlYWQodHBtdF9zdW0pCnRwbXRfcG9zX21lYW4gPC0gZ2dwbG90KHRwbXRfc3VtLCBhZXMoeD1wb3NpdGlvbiwgeT1zY29yZSkpKyBnZW9tX2Jhcihwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSgpLCBzdGF0PSJpZGVudGl0eSIsIGNvbG91cj0iIzk5OTk5OSIpICsgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1zY29yZS1zZCwgeW1heCA9IHNjb3JlK3NkKSwgd2lkdGg9MSwgc2l6ZT0wLjMsIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKCkpICt5bGFiKCJWQU1QLXNlcSBzY29yZSIpK3RoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCkpICsgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCAyNDUsIDEwKSwgZXhwYW5kID0gYygwLDApKSArIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsMCkpCiNmYWN0b3IocG9zaXRpb24pIGlzIGdldHRpbmcgcmlkIG9mIHNvbWUgcG9zaXRpb25zIGFsdG9nZXRoZXIgb24gdGhlIGdyYXBoCiN0cG10X3Bvc19tZWFuIDwtIGdncGxvdCh0cG10X3N1bSwgYWVzKHg9ZmFjdG9yKHBvc2l0aW9uKSwgeT1zY29yZSkpKyBnZW9tX2Jhcihwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSgpLCBzdGF0PSJpZGVudGl0eSIsIGNvbG91cj0iIzk5OTk5OSIpICsgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1zY29yZS1zZCwgeW1heCA9IHNjb3JlK3NkKSwgd2lkdGg9MC4wMDEsIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKCkpICt5bGFiKCJWQU1QLXNlcSBzY29yZSIpK3RoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCkpICsgc2NhbGVfeF9kaXNjcmV0ZShicmVha3MgPSBzZXEoMCwgMjUwLCAxMCkpCnRwbXRfaGVhdCA8LSBnZ3Bsb3QodHBtdDFfcHJvY193dCwgYWVzKHBvc2l0aW9uLCBlbmQpKSArIGdlb21fdGlsZShhZXMoZmlsbD1zY29yZSkpICsgc2NhbGVfZmlsbF9ncmFkaWVudG4oY29sb3VycyA9IGMoIiMzRjdDQjkiLCAiI0ZGRUFGMyIsICIjQjIxRjRFIiksIHZhbHVlcyA9IHNjYWxlczo6cmVzY2FsZShjKC0wLjcsIDAuMiwgMSwgMS4zLCAyLjAzKSkpKyBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDI0NSwgMTApLCBleHBhbmQ9YygwLDApKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0nYm90dG9tJykreGxhYigiUG9zaXRpb24gaW4gVFBNVCIpICsgc2NhbGVfeV9kaXNjcmV0ZShleHBhbmQgPSBjKDAsMCkpCiNzY2FsZV9maWxsX2dyYWRpZW50Mihsb3c9IiMzRjdDQjkiLCBtaWQ9IndoaXRlIiwgaGlnaD0iI0IyMUY0RSIsIG1pZHBvaW50PTEpIAojc2NhbGVfZmlsbF9kaXN0aWxsZXIocGFsZXR0ZT0gIlJkQnUiKQp0cG10X2Rzc3Bfc2NoZW1hdGljIDwtIGdncGxvdCgpICsgZ2d0aXRsZSgiVFBNVCBtZWFuIGFidW5kYW5jZSBzY29yZXMiKSArCiAgZ2VvbV9zZWdtZW50KGFlcyh4ID0gMSwgeSA9IDAsIHhlbmQgPSBtYXgodHBtdDFfZGF0YSRwb3NpdGlvbikpLCB5ZW5kID0gMCwgc2l6ZSA9IDEsIGNvbG9yID0gImdyZXk3MCIpICsKICBnZW9tX3BvaW50KGRhdGEgPSB0cG10MV9kYXRhLCBhZXMoeCA9IHBvc2l0aW9uLCB5ID0gMCksIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDEuOCkgKwogIGdlb21fcG9pbnQoZGF0YSA9IHN1YnNldCh0cG10MV9kYXRhLCBzaGVldCA9PSAxKSwgYWVzKHggPSBwb3NpdGlvbiwgeSA9IDApLCBjb2xvciA9ICJwaW5rIiwgc2l6ZSA9IDEuNSkgKwogIGdlb21fcG9pbnQoZGF0YSA9IHN1YnNldCh0cG10MV9kYXRhLCBoZWxpeCA9PSAxKSwgYWVzKHggPSBwb3NpdGlvbiwgeSA9IDApLCBjb2xvciA9ICJjeWFuIiwgc2l6ZSA9IDEuNSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMjQ1LCAxMCksIGV4cGFuZCA9IGMoMCwwKSkgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBOVUxMLCBleHBhbmQgPSBjKDAsMCkpICt4bGFiKE5VTEwpICsgeWxhYihOVUxMKSArCiAgdGhlbWUocGFuZWwuYm9yZGVyID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCkpCgojcGxvdHMKcGxvdCh0cG10X3Bvc19tZWFuKQpwbG90KHRwbXRfaGVhdCkKdHBtdF9kc3NwX3NjaGVtYXRpYwoKIysgZ2VvbV92bGluZSh4aW50ZXJjZXB0PTE4NSwgY29sb3I9ImJsYWNrIiwgc2l6ZT0uMSkgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9MzUwLCBjb2xvcj0iYmxhY2siLCBzaXplPS4xKQoKI2dyb3VwaW5nIGFsbCB2YXJpYW50cyBpbiB0aGUgc2FtZSBzZWNvbmRhcnkgc3RydWN0dXJlIHRvZ2V0aGVyCnRwbXRfYWFfc3VtIDwtIHN1bW1hcnlTRSh0cG10X2NvbG9ycywgbWVhc3VyZXZhcj0ic2NvcmUiLCBncm91cHZhcnM9ImZhY3QiKQp0cG10X2FhX21lYW4gPC0gZ2dwbG90KHRwbXRfYWFfc3VtLCBhZXMoeD1mYWN0LCB5PXNjb3JlKSkrIGdlb21fYmFyKHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKCksIHN0YXQ9ImlkZW50aXR5IiwgY29sb3VyPSIjOTk5OTk5IikgKyBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPXNjb3JlLXNkLCB5bWF4ID0gc2NvcmUrc2QpLCB3aWR0aD0xLCBzaXplPTAuMywgcG9zaXRpb249cG9zaXRpb25fZG9kZ2UoKSkgK3lsYWIoIlZBTVAtc2VxIHNjb3JlIikrdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCkpICsgc2NhbGVfeF9kaXNjcmV0ZShicmVha3MgPSBzZXEoMCwgMjQ1LCAxMCkpICsgeGxhYigiZWFjaCBiYXIgaXMgYSBkaWZmZXJlbnQgc2Vjb25kYXJ5IHN0cnVjdHVyZSIpCnBsb3QodHBtdF9hYV9tZWFuKQpgYGAKYGBge3J9CiNQVEVOCnB0ZW5fc3VtIDwtIHN1bW1hcnlTRShwdGVuMV9wcm9jX3d0LCBtZWFzdXJldmFyPSJzY29yZSIsIGdyb3VwdmFycz0icG9zaXRpb24iKQojaGVhZChwdGVuX3N1bSkKcHRlbl9wb3NfbWVhbiA8LSBnZ3Bsb3QocHRlbl9zdW0sIGFlcyh4PXBvc2l0aW9uLCB5PXNjb3JlKSkrIGdlb21fYmFyKHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKCksIHN0YXQ9ImlkZW50aXR5IiwgY29sb3VyPSIjOTk5OTk5IikgKyBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPXNjb3JlLXNkLCB5bWF4ID0gc2NvcmUrc2QpLCB3aWR0aD0xLCBzaXplPTAuMywgcG9zaXRpb249cG9zaXRpb25fZG9kZ2UoKSkgK3lsYWIoIlZBTVAtc2VxIHNjb3JlIikrdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSkgKyBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDQwMywgMjApLCBleHBhbmQgPSBjKDAsMCkpICsgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwwKSkgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9MTg1LCBjb2xvcj0iYmxhY2siLCBzaXplPS4xKSArIGdlb21fdmxpbmUoeGludGVyY2VwdD0zNTAsIGNvbG9yPSJibGFjayIsIHNpemU9LjEpCnB0ZW5faGVhdCA8LSBnZ3Bsb3QocHRlbjFfcHJvY193dCwgYWVzKHBvc2l0aW9uLCBlbmQpKSArIGdlb21fdGlsZShhZXMoZmlsbD1zY29yZSkpICsgc2NhbGVfZmlsbF9ncmFkaWVudG4oY29sb3VycyA9IGMoIiMzRjdDQjkiLCAiI0ZGRUFGMyIsICIjQjIxRjRFIiksIHZhbHVlcyA9IHNjYWxlczo6cmVzY2FsZShjKC0wLjIzLCAwLjQyLCAxLCAxLjIsIDEuNDcpKSkrIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgNDAzLCAyMCksIGV4cGFuZD1jKDAsMCkpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSdib3R0b20nKSt4bGFiKCJQb3NpdGlvbiBpbiBUUE1UIikgKyBzY2FsZV95X2Rpc2NyZXRlKGV4cGFuZCA9IGMoMCwwKSkKI2MoLTAuNywgMC4yLCAxLCAxLjMsIDIuMDMpCiNjKC0wLjIzLCAwLjQyLCAxLCAxLjIsIDEuNDcpCnB0ZW5fZXh0cmEgPC0gcmVhZC50YWJsZShmaWxlID0gJ34vbGVrbGFiL2xla2xhYi9QVEVOX3Bvc2l0aW9uYWxfZGF0YS50c3YnLCBzZXAgPSAnXHQnLCBoZWFkZXIgPSBUUlVFKQpwdGVuX2Rzc3Bfc2NoZW1hdGljIDwtIGdncGxvdCgpICsgZ2d0aXRsZSgiUFRFTiBtZWFuIGFidW5kYW5jZSBzY29yZXMiKSArCiAgZ2VvbV9zZWdtZW50KGFlcyh4ID0gMSwgeSA9IDAsIHhlbmQgPSBtYXgocHRlbl9leHRyYSRwb3NpdGlvbikpLCB5ZW5kID0gMCwgc2l6ZSA9IDEsIGNvbG9yID0gImdyZXk3MCIpICsKICBnZW9tX3BvaW50KGRhdGEgPSBzdWJzZXQocHRlbl9leHRyYSwgIWlzLm5hKHhjYSkpLCBhZXMoeCA9IHBvc2l0aW9uLCB5ID0gMCksIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDEuOCkgKwogIGdlb21fcG9pbnQoZGF0YSA9IHN1YnNldChwdGVuX2V4dHJhLCBzaGVldCA9PSAxKSwgYWVzKHggPSBwb3NpdGlvbiwgeSA9IDApLCBjb2xvciA9ICJwaW5rIiwgc2l6ZSA9IDEuNSkgKwogIGdlb21fcG9pbnQoZGF0YSA9IHN1YnNldChwdGVuX2V4dHJhLCBoZWxpeCA9PSAxKSwgYWVzKHggPSBwb3NpdGlvbiwgeSA9IDApLCBjb2xvciA9ICJjeWFuIiwgc2l6ZSA9IDEuNSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgNDAzLCAyMCksIGV4cGFuZCA9IGMoMCwwKSkgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBOVUxMLCBleHBhbmQgPSBjKDAsMCkpICt4bGFiKE5VTEwpICsgeWxhYihOVUxMKSArCiAgdGhlbWUocGFuZWwuYm9yZGVyID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCkpCgojcGxvdHMKcGxvdChwdGVuX3Bvc19tZWFuKQpwbG90KHB0ZW5faGVhdCkKcHRlbl9kc3NwX3NjaGVtYXRpYwoKYGBgCgoKYGBge3IgaW5jbHVkZT1GQUxTRX0KIy4uLnBvaW50bGVzcyB0byByZXByZXNlbnQgZGF0YSB0aGlzIHdheSAuLi4KCiNkYk5TRlAKI3NldHVwCnRwbXRfbWVyZ2VfY29weSA8LSB0cG10X21lcmdlCnRwbXRfbWVyZ2VfZXhwYW5kX2NvcHkgPC0gdHBtdF9tZXJnZV9leHBhbmQKI3RwbXRfbWVyZ2VfY29weSRTSUZUX2NvbnZlcnRlZF9yYW5rc2NvcmVbd2hpY2godHBtdF9tZXJnZV9jb3B5JFNJRlRfc2NvcmUgPT0gJy4nKV0gPSBOQQp0cG10X21lcmdlX2NvcHkkU0lGVF9zY29yZSA8LSBhcy5udW1lcmljKHRwbXRfbWVyZ2VfY29weSRTSUZUX3Njb3JlKQp0cG10X21lcmdlX2NvcHkkU0lGVF9jb252ZXJ0ZWRfcmFua3Njb3JlIDwtIGFzLm51bWVyaWModHBtdF9tZXJnZV9jb3B5JFNJRlRfY29udmVydGVkX3JhbmtzY29yZSkKdHBtdF9tZXJnZV9leHBhbmRfY29weSRQb2x5cGhlbjJfSFZBUl9zY29yZSA8LSBhcy5udW1lcmljKHRwbXRfbWVyZ2VfZXhwYW5kX2NvcHkkUG9seXBoZW4yX0hWQVJfc2NvcmUpCgojc2lmdF9zdW0KdHBtdF9zaWZ0X3N1bSA8LSBzdW1tYXJ5U0UodHBtdF9tZXJnZV9jb3B5LCBtZWFzdXJldmFyPSJTSUZUX3Njb3JlIiwgZ3JvdXB2YXJzPSJwb3NpdGlvbiIpCnRzc19wbG90IDwtIGdncGxvdCh0cG10X3NpZnRfc3VtLCBhZXMoeD1wb3NpdGlvbiwgeT1TSUZUX3Njb3JlKSkrIGdlb21fYmFyKHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKCksIHN0YXQ9ImlkZW50aXR5IiwgY29sb3VyPSIjOTk5OTk5IikgKyBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPVNJRlRfc2NvcmUtc2QsIHltYXggPVNJRlRfc2NvcmUrc2QpLCB3aWR0aD0xLCBzaXplPTAuMywgcG9zaXRpb249cG9zaXRpb25fZG9kZ2UoKSkgK3lsYWIoImRmTlNGUCBTSUZUIHNjb3JlIikrdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSkgKyBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDI0NSwgMTApLCBleHBhbmQgPSBjKDAsMCkpICsgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwwKSkKI3Bsb3QodHNzX3Bsb3QpCgojSFZBUl9zdW0KdHBtdF9odmFyX3N1bSA8LXN1bW1hcnlTRSh0cG10X21lcmdlX2V4cGFuZF9jb3B5LCBtZWFzdXJldmFyPSJQb2x5cGhlbjJfSFZBUl9zY29yZSIsIGdyb3VwdmFycz0icG9zaXRpb24iKQp0aHNfcGxvdCA8LSBnZ3Bsb3QodHBtdF9odmFyX3N1bSwgYWVzKHg9cG9zaXRpb24sIHk9UG9seXBoZW4yX0hWQVJfc2NvcmUpKSsgZ2VvbV9iYXIocG9zaXRpb249cG9zaXRpb25fZG9kZ2UoKSwgc3RhdD0iaWRlbnRpdHkiLCBjb2xvdXI9IiM5OTk5OTkiKSArIGdlb21fZXJyb3JiYXIoYWVzKHltaW49UG9seXBoZW4yX0hWQVJfc2NvcmUtc2QsIHltYXggPVBvbHlwaGVuMl9IVkFSX3Njb3JlK3NkKSwgd2lkdGg9MSwgc2l6ZT0wLjMsIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKCkpICt5bGFiKCJkZk5TRlAgSFZBUiBzY29yZSIpK3RoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCkpICsgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCAyNDUsIDEwKSwgZXhwYW5kID0gYygwLDApKSArIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsMCkpCiNwbG90KHRoc19wbG90KQpgYGAKCmBgYHtyfQojbWV0aG9kMSAoYmFzaWMsIGZvciB2aXN1YWxpemluZyBpbiByc3R1ZGlvKQpncmlkLm5ld3BhZ2UoKQpncmlkLmRyYXcocmJpbmQoZ2dwbG90R3JvYih0cG10X2Rzc3Bfc2NoZW1hdGljKSwgZ2dwbG90R3JvYih0cG10X3Bvc19tZWFuKSwgZ2dwbG90R3JvYih0cG10X2hlYXQpLCBzaXplID0gImxhc3QiKSkKCmdyaWQubmV3cGFnZSgpCmdyaWQuZHJhdyhyYmluZChnZ3Bsb3RHcm9iKHB0ZW5fZHNzcF9zY2hlbWF0aWMpLCBnZ3Bsb3RHcm9iKHB0ZW5fcG9zX21lYW4pLCBnZ3Bsb3RHcm9iKHB0ZW5faGVhdCksIHNpemUgPSAibGFzdCIpKQoKI21ldGhvZDIgKHVzZSBmb3IgZmluYWwgbGF5b3V0LCBzaXplIHNwZWNpZmljYXRpb24sIGRvd25sb2FkKQpnQT1nZ3Bsb3RfZ3RhYmxlKGdncGxvdF9idWlsZCh0cG10X3Bvc19tZWFuKSkKZ0I9Z2dwbG90X2d0YWJsZShnZ3Bsb3RfYnVpbGQodHBtdF9oZWF0KSkKZ0M9Z2dwbG90X2d0YWJsZShnZ3Bsb3RfYnVpbGQodHBtdF9kc3NwX3NjaGVtYXRpYykpCmdhPWdncGxvdF9ndGFibGUoZ2dwbG90X2J1aWxkKHB0ZW5fcG9zX21lYW4pKQpnYj1nZ3Bsb3RfZ3RhYmxlKGdncGxvdF9idWlsZChwdGVuX2hlYXQpKQpnYz1nZ3Bsb3RfZ3RhYmxlKGdncGxvdF9idWlsZChwdGVuX2Rzc3Bfc2NoZW1hdGljKSkKbWF4V2lkdGggPSBncmlkOjp1bml0LnBtYXgoZ0Ekd2lkdGhzLCBnQiR3aWR0aHMsIGdDJHdpZHRocywgZ2Ekd2lkdGhzLCBnYiR3aWR0aHMsIGdjJHdpZHRocykKZ0Ekd2lkdGhzIDwtIGFzLmxpc3QobWF4V2lkdGgpCmdCJHdpZHRocyA8LSBhcy5saXN0KG1heFdpZHRoKQpnQyR3aWR0aHMgPC0gYXMubGlzdChtYXhXaWR0aCkKZ2Ekd2lkdGhzIDwtIGFzLmxpc3QobWF4V2lkdGgpCmdiJHdpZHRocyA8LSBhcy5saXN0KG1heFdpZHRoKQpnYyR3aWR0aHMgPC0gYXMubGlzdChtYXhXaWR0aCkKCmdyaWQubmV3cGFnZSgpCgojc3RvcmluZywgd2l0aCBzcGVjaWZpZWQgd2lkdGhzISEKcGRmKCdwdGVuX3RwbXRfbWVhbl9oZWF0LnBkZicsIHdpZHRoPTgsIGhlaWdodD02KQpncmlkLmFycmFuZ2UoYXJyYW5nZUdyb2IoZ0MsZ0EsZ0IsbnJvdz0zLGhlaWdodHM9YyguMSwuMywuOCkpKQpncmlkLmFycmFuZ2UoYXJyYW5nZUdyb2IoZ2MsZ2EsZ2IsbnJvdz0zLGhlaWdodHM9YyguMSwuMywuOCkpKQpkZXYub2ZmKCkKYGBgCmBgYHtyIGluY2x1ZGU9RkFMU0V9CiMjYXR0ZW1wdCB0byBvcmRlciBieSBhYnVuZGFuY2UuLi4KI3RwbXRfc3VtX28gPC0gdHBtdF9zdW1bb3JkZXIodHBtdF9zdW0kc2NvcmUpLF0KI3RwbXRfc3VtX28kcG9zaXRpb24gPC0gZmFjdG9yKHRwbXRfc3VtX28kcG9zaXRpb24sIGxldmVscz10cG10X3N1bV9vJHBvc2l0aW9uW29yZGVyKHRwbXRfc3VtX28kc2NvcmUpXSkKI3RwbXRfcG9zX21lYW5fbyA8LSBnZ3Bsb3QodHBtdF9zdW1fbywgYWVzKHg9ZmFjdG9yKHBvc2l0aW9uKSwgeT1zY29yZSkpKyBnZW9tX2Jhcihwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSgpLCBzdGF0PSJpZGVudGl0eSIsIGNvbG91cj0iIzk5OTk5OSIpICsgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1zY29yZS1zZCwgeW1heCA9IHNjb3JlK3NkKSwgd2lkdGg9MC4wMDEsIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKCkpICt5bGFiKCJWQU1QLXNlcSBzY29yZSIpK3RoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCkpICsgc2NhbGVfeF9kaXNjcmV0ZShicmVha3MgPSBzZXEoMCwgMjUwLCAxMCkpCiNhYWEgPC0gdHBtdDFfcHJvY193dAojYWFhJG1lYW5zIDwtIHRwbXRfc3VtW21hdGNoKGFhYSRwb3NpdGlvbiwgdHBtdF9zdW0kcG9zaXRpb24pLDJdCiNiYmIgPC0gYWFhW29yZGVyKGFhYSRtZWFuKSxdCiNiYmIkcG9zaXRpb24gPC0gYXMuZmFjdG9yKGJiYiRwb3NpdGlvbikKI3RwbXRfaGVhdF9vIDwtIGdncGxvdChiYmIsIGFlcyh4PWZhY3Rvcihwb3NpdGlvbiksIHk9ZW5kKSkgKyBnZW9tX3RpbGUoYWVzKGZpbGw9c2NvcmUpKSArIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKGNvbG91cnMgPSBjKCIjM0Y3Q0I5IiwgIiNGRkVBRjMiLCAiI0IyMUY0RSIpLCB2YWx1ZXMgPSBzY2FsZXM6OnJlc2NhbGUoYygtMC43LCAwLjIsIDEsIDEuMywgMi4wMykpKSsgc2NhbGVfeF9kaXNjcmV0ZShicmVha3MgPSBzZXEoMCwgMjUwLCAxMCkpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSdib3R0b20nKSt4bGFiKCJQb3NpdGlvbiBpbiBUUE1UIikKCiNhYWEkcG9zaXRpb24gPC0gZmFjdG9yKGFhYSRwb3NpdGlvbiwgbGV2ZWxzPXVuaXF1ZShhYWEkcG9zaXRpb24pW29yZGVyKGFhYSRtZWFucyldKQojdHBtdF9oZWF0X28gPC0gZ2dwbG90KGFhYSwgYWVzKHg9ZmFjdG9yKG1lYW4pLCB5PWVuZCkpICsgZ2VvbV90aWxlKGFlcyhmaWxsPXNjb3JlKSkgKyBzY2FsZV9maWxsX2dyYWRpZW50bihjb2xvdXJzID0gYygiIzNGN0NCOSIsICIjRkZFQUYzIiwgIiNCMjFGNEUiKSwgdmFsdWVzID0gc2NhbGVzOjpyZXNjYWxlKGMoLTAuNywgMC4yLCAxLCAxLjMsIDIuMDMpKSkrIHNjYWxlX3hfZGlzY3JldGUoYnJlYWtzID0gc2VxKDAsIDI1MCwgMTApKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0nYm90dG9tJykreGxhYigiUG9zaXRpb24gaW4gVFBNVCIpCiN0cG10X2Rzc3Bfc2NoZW1hdGljIDwtIGdncGxvdCgpICsgZ2d0aXRsZSgiVFBNVCBtZWFuIGFidW5kYW5jZSBzY29yZXMiKSArCiMgIGdlb21fc2VnbWVudChhZXMoeCA9IDEsIHkgPSAwLCB4ZW5kID0gbWF4KHRwbXQxX2RhdGEkcG9zaXRpb24pKSwgeWVuZCA9IDAsIHNpemUgPSAxLCBjb2xvciA9ICJncmV5NzAiKSArCiMgIGdlb21fcG9pbnQoZGF0YSA9IHRwbXQxX2RhdGEsIGFlcyh4ID0gcG9zaXRpb24sIHkgPSAwKSwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gMS44KSArCiMgIGdlb21fcG9pbnQoZGF0YSA9IHN1YnNldCh0cG10MV9kYXRhLCBzaGVldCA9PSAxKSwgYWVzKHggPSBwb3NpdGlvbiwgeSA9IDApLCBjb2xvciA9ICJwaW5rIiwgc2l6ZSA9IDEuNSkgKwojICBnZW9tX3BvaW50KGRhdGEgPSBzdWJzZXQodHBtdDFfZGF0YSwgaGVsaXggPT0gMSksIGFlcyh4ID0gcG9zaXRpb24sIHkgPSAwKSwgY29sb3IgPSAiY3lhbiIsIHNpemUgPSAxLjUpICsKIyAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCAyNTAsIDEwKSwgZXhwYW5kID0gYygwLDApKSArCiMgIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBOVUxMLCBleHBhbmQgPSBjKDAsMCkpICt4bGFiKE5VTEwpICsgeWxhYihOVUxMKSArCiMgIHRoZW1lKHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpKQojdHBtdF9kc3NwX3NjaGVtYXRpYwojcGxvdCh0cG10X3Bvc19tZWFuX28pCiNwbG90KHRwbXRfaGVhdF9vKQpgYGAKYGBge3J9CiNwbG90dGluZyBtZWFuIHNjb3JlIHZzIHZhcmlhbnQgY2hhbmdlZCB0byAKdHBtdF9lbmRfc3VtIDwtIHN1bW1hcnlTRSh0cG10MV9wcm9jX3d0LCBtZWFzdXJldmFyPSJzY29yZSIsIGdyb3VwdmFycz0iZW5kIikKdHBtdF9lbmRfbWVhbiA8LSBnZ3Bsb3QodHBtdF9lbmRfc3VtLCBhZXMoeD1lbmQsIHk9c2NvcmUpKSArCiAgZ2VvbV9iYXIocG9zaXRpb249cG9zaXRpb25fZG9kZ2UoKSwgc3RhdD0iaWRlbnRpdHkiLCBjb2xvdXI9IiM5OTk5OTkiKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1zY29yZS1zZCwgeW1heD1zY29yZStzZCksIHdpZHRoPTAuMDAxLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSgpKSArCiAgeWxhYigibWVhbiBhYnVuZGFuY2UiKSArIHhsYWIoInZhcmlhbnQgYW1pbm8gYWNpZCIpCnBsb3QodHBtdF9lbmRfbWVhbikKCmBgYApgYGB7ciBpbmNsdWRlPUZBTFNFfQojcGxvdHRpbmcgc2NvcmVzIHZzIGVuZCBjb2xvcmVkIGJ5IGxvY2F0aW9uL3NlY29uZGFyeSBzdHJ1Y3R1cmUKI3RwbXRfZW5kX3Njb3Jlc19iIDwtIGdncGxvdChkYXRhPXN1YnNldCh0cG10MV9wcm9jX3d0LCBzaGVldD09MSksIGFlcyh4PWVuZCwgeT1zY29yZSwgY29sb3VyPXBvc2l0aW9uKSkgKwojICBnZW9tX3Zpb2xpbihkYXRhPXN1YnNldCh0cG10MV9wcm9jX3d0LCBzaGVldD09MSksIGRyYXdfcXVhbnRpbGVzPTAuNSwgc2NhbGUgPSAid2lkdGgiKSArCiMgIGdlb21fcG9pbnQoZGF0YT1zdWJzZXQodHBtdDFfcHJvY193dCwgc2hlZXQ9PTEpLCBzaXplPS4zLCBhbHBoYSA9IDAuNiwgcG9zaXRpb249aml0dGVyMikgKyB5bGFiKCJhYnVuZGFuY2UiKSArIHhsYWIoInZhcmlhbnQgYWEiKSArCiMgIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC0wLjgsIDIuMikpCgojdHBtdF9lbmRfc2NvcmVzX2EgPC0gZ2dwbG90KGRhdGE9c3Vic2V0KHRwbXQxX3Byb2Nfd3QsIGhlbGl4PT0xKSwgYWVzKHg9ZW5kLCB5PXNjb3JlLCBjb2xvdXI9cG9zaXRpb24pKSArCiMgIGdlb21fdmlvbGluKGRhdGE9c3Vic2V0KHRwbXQxX3Byb2Nfd3QsIGhlbGl4PT0xKSwgZHJhd19xdWFudGlsZXM9MC41LCBzY2FsZSA9ICJ3aWR0aCIpICsKIyAgZ2VvbV9wb2ludChkYXRhPXN1YnNldCh0cG10MV9wcm9jX3d0LCBoZWxpeD09MSksIHNpemU9LjMsIGFscGhhID0gMC42LCBwb3NpdGlvbj1qaXR0ZXIyKSArIHlsYWIoImFidW5kYW5jZSIpICsgeGxhYigidmFyaWFudCBhYSIpICsKIyAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTAuOCwgMi4yKSkKCiN0cG10X2VuZF9zY29yZXNfbiA8LSBnZ3Bsb3QoZGF0YT1zdWJzZXQodHBtdDFfcHJvY193dCwgc2Vjb25kYXJ5X3N0cnVjdD09Im5laXRoZXIiKSwgYWVzKHg9ZW5kLCB5PXNjb3JlLCBjb2xvdXI9cG9zaXRpb24pKSArCiMgIGdlb21fdmlvbGluKGRhdGE9c3Vic2V0KHRwbXQxX3Byb2Nfd3QsIHNlY29uZGFyeV9zdHJ1Y3Q9PSJuZWl0aGVyIiksIGRyYXdfcXVhbnRpbGVzPTAuNSwgc2NhbGUgPSAid2lkdGgiKSArCiMgIGdlb21fcG9pbnQoZGF0YT1zdWJzZXQodHBtdDFfcHJvY193dCwgc2Vjb25kYXJ5X3N0cnVjdD09Im5laXRoZXIiKSwgc2l6ZT0uMywgYWxwaGEgPSAwLjYsIHBvc2l0aW9uPWppdHRlcjIpICsgeWxhYigiYWJ1bmRhbmNlIikgKyB4bGFiKCJ2YXJpYW50IGFhIikgKwojICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtMC44LCAyLjIpKQoKI3Bsb3QodHBtdF9lbmRfc2NvcmVzX2IpCiNwbG90KHRwbXRfZW5kX3Njb3Jlc19hKQojcGxvdCh0cG10X2VuZF9zY29yZXNfbikKCiN0cG10X2VuZF9zY29yZXNfNjAgPC0gZ2dwbG90KGRhdGE9c3Vic2V0KHRwbXQxX3Byb2Nfd3QsIHBvc2l0aW9uPD02MCksIGFlcyh4PWVuZCwgeT1zY29yZSwgY29sb3VyPXBvc2l0aW9uKSkgKwojICBnZW9tX3Zpb2xpbihkYXRhPXN1YnNldCh0cG10MV9wcm9jX3d0LCBwb3NpdGlvbjw9NjApLCBkcmF3X3F1YW50aWxlcz0wLjUsIHNjYWxlID0gIndpZHRoIikgKwojICBnZW9tX3BvaW50KGRhdGE9c3Vic2V0KHRwbXQxX3Byb2Nfd3QsIHBvc2l0aW9uPD02MCksIHNpemU9LjMsIGFscGhhID0gMC42LCBwb3NpdGlvbj1qaXR0ZXIyKSArIHlsYWIoImFidW5kYW5jZSIpICsgeGxhYigidmFyaWFudCBhYSIpICsKIyAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTAuOCwgMi4yKSkKI3RwbXRfZW5kX3Njb3Jlc18xMjAgPC0gZ2dwbG90KGRhdGE9c3Vic2V0KHRwbXQxX3Byb2Nfd3QsIHBvc2l0aW9uPjYwICYgcG9zaXRpb248PTEyMCksIGFlcyh4PWVuZCwgeT1zY29yZSwgY29sb3VyPXBvc2l0aW9uKSkgKwojICBnZW9tX3Zpb2xpbihkYXRhPXN1YnNldCh0cG10MV9wcm9jX3d0LCBwb3NpdGlvbj42MCAmIHBvc2l0aW9uPD0xMjApLCBkcmF3X3F1YW50aWxlcz0wLjUsIHNjYWxlID0gIndpZHRoIikgKwojICBnZW9tX3BvaW50KGRhdGE9c3Vic2V0KHRwbXQxX3Byb2Nfd3QsIHBvc2l0aW9uPjYwICYgcG9zaXRpb248PTEyMCksIHNpemU9LjMsIGFscGhhID0gMC42LCBwb3NpdGlvbj1qaXR0ZXIyKSArIHlsYWIoImFidW5kYW5jZSIpICsgeGxhYigidmFyaWFudCBhYSIpICsKIyAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTAuOCwgMi4yKSkKI3RwbXRfZW5kX3Njb3Jlc18xODAgPC0gZ2dwbG90KGRhdGE9c3Vic2V0KHRwbXQxX3Byb2Nfd3QsIHBvc2l0aW9uPjEyMCAmIHBvc2l0aW9uPD0xODApLCBhZXMoeD1lbmQsIHk9c2NvcmUsIGNvbG91cj1wb3NpdGlvbikpICsKIyAgZ2VvbV92aW9saW4oZGF0YT1zdWJzZXQodHBtdDFfcHJvY193dCwgcG9zaXRpb24+MTIwICYgcG9zaXRpb248PTE4MCksIGRyYXdfcXVhbnRpbGVzPTAuNSwgc2NhbGUgPSAid2lkdGgiKSArCiMgIGdlb21fcG9pbnQoZGF0YT1zdWJzZXQodHBtdDFfcHJvY193dCwgcG9zaXRpb24+MTIwICYgcG9zaXRpb248PTE4MCksIHNpemU9LjMsIGFscGhhID0gMC42LCBwb3NpdGlvbj1qaXR0ZXIyKSArIHlsYWIoImFidW5kYW5jZSIpICsgeGxhYigidmFyaWFudCBhYSIpICsKIyAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTAuOCwgMi4yKSkKI3RwbXRfZW5kX3Njb3Jlc18yNDUgPC0gZ2dwbG90KGRhdGE9c3Vic2V0KHRwbXQxX3Byb2Nfd3QsIHBvc2l0aW9uPjE4MCAmIHBvc2l0aW9uPD0yNDUpLCBhZXMoeD1lbmQsIHk9c2NvcmUsIGNvbG91cj1wb3NpdGlvbikpICsKIyAgZ2VvbV92aW9saW4oZGF0YT1zdWJzZXQodHBtdDFfcHJvY193dCwgcG9zaXRpb24+MTgwICYgcG9zaXRpb248PTI0NSksIGRyYXdfcXVhbnRpbGVzPTAuNSwgc2NhbGUgPSAid2lkdGgiKSArCiMgIGdlb21fcG9pbnQoZGF0YT1zdWJzZXQodHBtdDFfcHJvY193dCwgcG9zaXRpb24+MTgwICYgcG9zaXRpb248PTI0NSksIHNpemU9LjMsIGFscGhhID0gMC42LCBwb3NpdGlvbj1qaXR0ZXIyKSArIHlsYWIoImFidW5kYW5jZSIpICsgeGxhYigidmFyaWFudCBhYSIpICsKIyAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTAuOCwgMi4yKSkKCiNwbG90KHRwbXRfZW5kX3Njb3Jlc182MCkKI3Bsb3QodHBtdF9lbmRfc2NvcmVzXzEyMCkKI3Bsb3QodHBtdF9lbmRfc2NvcmVzXzE4MCkKI3Bsb3QodHBtdF9lbmRfc2NvcmVzXzI0NSkKYGBgCgoKYGBge3J9CnNldC5zZWVkKDE1MykKaml0dGVyIDwtIHBvc2l0aW9uX2ppdHRlcih3aWR0aCA9IDEsIGhlaWdodCA9IE5VTEwpCmppdHRlcjEgPC1wb3NpdGlvbl9qaXR0ZXIod2lkdGggPSAwLjA4LCBoZWlnaHQgPSBOVUxMKQpqaXR0ZXIyIDwtIHBvc2l0aW9uX2ppdHRlcih3aWR0aD0wLjEzLCBoZWlnaHQgPSBOVUxMKQp0d2VudHlfY29sb3IgPSBjKCIjRDAyMDI4IiwgIiNFMUExMkYiLCAiI0VERDk0MSIsICIjRjJGMDhFIiwgIiNFRUM4OTgiLCAiI0JDRERBRSIsICIjQTRDMzNCIiwgIiM3NkMxNTgiLCAiIzg1NzgyRSIsICIjMzE1OTM1IiwgIiM1Mzk1OEIiLCAiI0ExREFFMCIsICIjNDg2RUI2IiwgIiNFNkEzQjQiLCAiI0M1QTBDQSIsICIjNTU0REEwIiwgIiM5OTI0N0UiLCAiIzQwMjA1OSIsICIjODI0MjFCIiwgIiM3RTgwN0UiLCAnYmxhY2snKQoKI3B0ZW5fa19zcHJlYWQxIDwtIGdncGxvdChwdGVuMV9wcm9jX3d0LCBhZXMoeT1zY29yZSwgeD1zdGFydCkpICsgZ2VvbV92aW9saW4oZHJhd19xdWFudGlsZXM9YygwLjUpLCBkYXRhPXN1YnNldChwdGVuMV9wcm9jX3d0LCBzdGFydD09ICJLIiksIGFlcyhncm91cD1mYWN0b3IocG9zaXRpb24pKSkgKyB4bGFiKCJQb3NpdGlvbiBpbiBQVEVOIikgKyBnZ3RpdGxlKCJMeXNpbmUgdmFyaWFudCBhYnVuZGFuY2Ugc2NvcmVzIikKCnB0ZW5fa19zcHJlYWQxIDwtIGdncGxvdChwdGVuMV9wcm9jX3d0LCBhZXMoeT1zY29yZSwgeD1mYWN0b3IocG9zaXRpb24pLCBjb2xvdXIgPSBlbmQpKSArIGdlb21fdmlvbGluKGRyYXdfcXVhbnRpbGVzPWMoMC41KSwgZGF0YT1zdWJzZXQocHRlbjFfcHJvY193dCwgc3RhcnQ9PSAiSyIpLCBhZXMoZ3JvdXA9ZmFjdG9yKHBvc2l0aW9uKSksIHNjYWxlID0gIndpZHRoIikgKyB4bGFiKCJQb3NpdGlvbiBpbiBQVEVOIikgKyBnZ3RpdGxlKCJMeXNpbmUgdmFyaWFudCBhYnVuZGFuY2Ugc2NvcmVzIikrIGdlb21fcG9pbnQoZGF0YT1zdWJzZXQocHRlbjFfcHJvY193dCwgc3RhcnQ9PSAiSyIpLCBhZXMoeD1mYWN0b3IocG9zaXRpb24pLCB5PXNjb3JlKSwgYWxwaGEgPSAwLjg1LCBwb3NpdGlvbj1qaXR0ZXIyKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9dHdlbnR5X2NvbG9yKQpwdGVuX2tfYWEgPC0gZ2dwbG90KHB0ZW4xX3Byb2Nfd3QsIGFlcyh5PXNjb3JlLCB4PWVuZCwgY29sb3VyID0gZW5kKSkgKyBnZW9tX3Zpb2xpbihkcmF3X3F1YW50aWxlcz1jKDAuNSksIGRhdGE9c3Vic2V0KHB0ZW4xX3Byb2Nfd3QsIHN0YXJ0PT0gIksiKSwgYWVzKGdyb3VwPWVuZCksIHNjYWxlID0gIndpZHRoIikgKyB4bGFiKCJBbWlubyBhY2lkIikgKyBnZ3RpdGxlKCJMeXNpbmUgdmFyaWFudCBhYnVuZGFuY2Ugc2NvcmVzIikrIGdlb21fcG9pbnQoZGF0YT1zdWJzZXQocHRlbjFfcHJvY193dCwgc3RhcnQ9PSAiSyIpLCBhZXMoeD1lbmQsIHk9c2NvcmUpLCBhbHBoYSA9IDAuNzUsIHBvc2l0aW9uPWppdHRlcjEpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz10d2VudHlfY29sb3IpCgpwdGVuX2dfc3ByZWFkMSA8LSBnZ3Bsb3QocHRlbjFfcHJvY193dCwgYWVzKHk9c2NvcmUsIHg9ZmFjdG9yKHBvc2l0aW9uKSwgY29sb3VyID0gZW5kKSkgKyBnZW9tX3Zpb2xpbihkcmF3X3F1YW50aWxlcz1jKDAuNSksIGRhdGE9c3Vic2V0KHB0ZW4xX3Byb2Nfd3QsIHN0YXJ0PT0gIkciKSwgYWVzKGdyb3VwPWZhY3Rvcihwb3NpdGlvbikpLCBzY2FsZSA9ICJ3aWR0aCIpICsgeGxhYigiUG9zaXRpb24gaW4gUFRFTiIpICsgZ2d0aXRsZSgiR2x5Y2luZSB2YXJpYW50IGFidW5kYW5jZSBzY29yZXMiKSsgZ2VvbV9wb2ludChkYXRhPXN1YnNldChwdGVuMV9wcm9jX3d0LCBzdGFydD09ICJHIiksIGFlcyh4PWZhY3Rvcihwb3NpdGlvbiksIHk9c2NvcmUpLCBhbHBoYSA9IDAuODUsIHBvc2l0aW9uPWppdHRlcjIpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz10d2VudHlfY29sb3IpCnB0ZW5fZ19hYSA8LSBnZ3Bsb3QocHRlbjFfcHJvY193dCwgYWVzKHk9c2NvcmUsIHg9ZW5kLCBjb2xvdXIgPSBlbmQpKSArIGdlb21fdmlvbGluKGRyYXdfcXVhbnRpbGVzPWMoMC41KSwgZGF0YT1zdWJzZXQocHRlbjFfcHJvY193dCwgc3RhcnQ9PSAiRyIpLCBhZXMoZ3JvdXA9ZW5kKSwgc2NhbGUgPSAid2lkdGgiKSArIHhsYWIoIkFtaW5vIGFjaWQiKSArIGdndGl0bGUoIkdseWNpbmUgdmFyaWFudCBhYnVuZGFuY2Ugc2NvcmVzIikrIGdlb21fcG9pbnQoZGF0YT1zdWJzZXQocHRlbjFfcHJvY193dCwgc3RhcnQ9PSAiRyIpLCBhZXMoeD1lbmQsIHk9c2NvcmUpLCBhbHBoYSA9IDAuNzUsIHBvc2l0aW9uPWppdHRlcjEpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz10d2VudHlfY29sb3IpCnB0ZW5fZ19oeWRyb2RpZmYgPC0gZ2dwbG90KHB0ZW4xX3Byb2Nfd3QsIGFlcyh5PXNjb3JlLCB4PWZhY3Rvcihwb3NpdGlvbiksIGNvbG91ciA9IChoeWRybzItaHlkcm8xKSkpICsgZ2VvbV92aW9saW4oZHJhd19xdWFudGlsZXM9YygwLjUpLCBkYXRhPXN1YnNldChwdGVuMV9wcm9jX3d0LCBzdGFydD09ICJHIiksIGFlcyhncm91cD1mYWN0b3IocG9zaXRpb24pKSwgc2NhbGUgPSAid2lkdGgiKSArIHhsYWIoIlBvc2l0aW9uIGluIFBURU4iKSArIGdndGl0bGUoIkdseWNpbmUgdmFyaWFudCBhYnVuZGFuY2Ugc2NvcmVzIHcvIGh5ZHJvcGhvYmljaXR5IGNoYW5nZSIpKyBnZW9tX3BvaW50KGRhdGE9c3Vic2V0KHB0ZW4xX3Byb2Nfd3QsIHN0YXJ0PT0gIkciKSwgYWVzKHg9ZmFjdG9yKHBvc2l0aW9uKSwgeT1zY29yZSksIGFscGhhID0gMC44NSwgcG9zaXRpb249aml0dGVyMikgKyBzY2FsZV9jb2xvcl9kaXN0aWxsZXIocGFsZXR0ZSA9ICJTcGVjdHJhbCIpCgpwdGVuX2Nfc3ByZWFkIDwtIGdncGxvdChwdGVuMV9wcm9jX3d0LCBhZXMoeT1zY29yZSwgeD1wb3NpdGlvbikpICsgZ2VvbV9wb2ludChkYXRhPXN1YnNldChwdGVuMV9wcm9jX3d0LCBzdGFydD09ICJDIikpICsgeGxhYigiUG9zaXRpb24gaW4gUFRFTiIpICsgZ2d0aXRsZSgiQ3lzdGVpbmUgdmFyaWFudCBhYnVuZGFuY2Ugc2NvcmVzIikKI2V4cGVyaW1lbnRfb3JpZwojcHRlbl9jX3NwcmVhZDEgPC0gZ2dwbG90KHB0ZW4xX3Byb2Nfd3QsIGFlcyh5PXNjb3JlLCB4PXBvc2l0aW9uLCBjb2xvdXIgPSBlbmQpKSArIGdlb21fdmlvbGluKGRyYXdfcXVhbnRpbGVzPWMoMC41KSwgZGF0YT1zdWJzZXQocHRlbjFfcHJvY193dCwgc3RhcnQ9PSAiQyIpLCBhZXMoZ3JvdXA9cG9zaXRpb24lJTQ1MCksIHNjYWxlID0gIndpZHRoIikgKyB4bGFiKCJQb3NpdGlvbiBpbiBQVEVOIikgKyBnZ3RpdGxlKCJDeXN0ZWluZSB2YXJpYW50IGFidW5kYW5jZSBzY29yZXMiKSsgZ2VvbV9wb2ludChkYXRhPXN1YnNldChwdGVuMV9wcm9jX3d0LCBzdGFydD09ICJDIiksIGFlcyh4PXBvc2l0aW9uLCB5PXNjb3JlKSwgYWxwaGEgPSAwLjc1LCBwb3NpdGlvbj1qaXR0ZXIpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jKCIjRDAyMDI4IiwgIiNFMUExMkYiLCAiI0VERDk0MSIsICIjRjJGMDhFIiwgIiNFRUM4OTgiLCAiI0JDRERBRSIsICIjQTRDMzNCIiwgIiM3NkMxNTgiLCAiIzg1NzgyRSIsICIjMzE1OTM1IiwgIiM1Mzk1OEIiLCAiI0ExREFFMCIsICIjNDg2RUI2IiwgIiNFNkEzQjQiLCAiI0M1QTBDQSIsICIjNTU0REEwIiwgIiM5OTI0N0UiLCAiIzQwMjA1OSIsICIjODI0MjFCIiwgIiM3RTgwN0UiLCAnYmxhY2snKSkKIywgc2NhbGUgPSAiY291bnQiCiMrIGdlb21fcG9pbnQoZGF0YT1zdWJzZXQocHRlbjFfcHJvY193dCwgc3RhcnQ9PSAiQyIpLCBhZXMoeD1wb3NpdGlvbiwgeT1zY29yZSksIGFscGhhID0gMC41KQpwdGVuX2Nfc3ByZWFkMSA8LSBnZ3Bsb3QocHRlbjFfcHJvY193dCwgYWVzKHk9c2NvcmUsIHg9cG9zaXRpb24sIGNvbG91ciA9IGVuZCkpICsgZ2VvbV92aW9saW4oZHJhd19xdWFudGlsZXM9YygwLjUpLCBkYXRhPXN1YnNldChwdGVuMV9wcm9jX3d0LCBzdGFydD09ICJDIiksIGFlcyhncm91cD1wb3NpdGlvbiUlNDUwKSwgc2NhbGUgPSAid2lkdGgiKSArIHhsYWIoIlBvc2l0aW9uIGluIFBURU4iKSArIGdndGl0bGUoIkN5c3RlaW5lIHZhcmlhbnQgYWJ1bmRhbmNlIHNjb3JlcyIpKyBnZW9tX3BvaW50KGRhdGE9c3Vic2V0KHB0ZW4xX3Byb2Nfd3QsIHN0YXJ0PT0gIkMiKSwgYWVzKHg9cG9zaXRpb24sIHk9c2NvcmUpLCBhbHBoYSA9IDAuNzUsIHBvc2l0aW9uPWppdHRlcjEpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz10d2VudHlfY29sb3IpCnB0ZW5fY19hYSA8LSBnZ3Bsb3QocHRlbjFfcHJvY193dCwgYWVzKHk9c2NvcmUsIHg9ZW5kLCBjb2xvdXIgPSBlbmQpKSArIGdlb21fdmlvbGluKGRyYXdfcXVhbnRpbGVzPWMoMC41KSwgZGF0YT1zdWJzZXQocHRlbjFfcHJvY193dCwgc3RhcnQ9PSAiQyIpLCBhZXMoZ3JvdXA9ZW5kKSwgc2NhbGUgPSAid2lkdGgiKSArIHhsYWIoIkFtaW5vIGFjaWQiKSArIGdndGl0bGUoIkN5c3RlaW5lIHZhcmlhbnQgYWJ1bmRhbmNlIHNjb3JlcyIpKyBnZW9tX3BvaW50KGRhdGE9c3Vic2V0KHB0ZW4xX3Byb2Nfd3QsIHN0YXJ0PT0gIkMiKSwgYWVzKHg9ZW5kLCB5PXNjb3JlKSwgYWxwaGEgPSAwLjc1LCBwb3NpdGlvbj1qaXR0ZXIxKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9dHdlbnR5X2NvbG9yKQoKcHRlbl9jX2h5ZHJvZGlmZiA8LSBnZ3Bsb3QocHRlbjFfcHJvY193dCwgYWVzKHk9c2NvcmUsIHg9cG9zaXRpb24sIGNvbG91ciA9IChoeWRybzItaHlkcm8xKSkpICsgZ2VvbV92aW9saW4oZHJhd19xdWFudGlsZXM9YygwLjUpLCBkYXRhPXN1YnNldChwdGVuMV9wcm9jX3d0LCBzdGFydD09ICJDIiksIGFlcyhncm91cD1wb3NpdGlvbiUlNDUwKSwgc2NhbGUgPSAid2lkdGgiKSArIHhsYWIoIlBvc2l0aW9uIGluIFBURU4iKSArIGdndGl0bGUoIkN5c3RlaW5lIHZhcmlhbnQgYWJ1bmRhbmNlIHNjb3JlcyB3LyBoeWRyb3Bob2JpY2l0eSBjaGFuZ2UiKSsgZ2VvbV9wb2ludChkYXRhPXN1YnNldChwdGVuMV9wcm9jX3d0LCBzdGFydD09ICJDIiksIGFlcyh4PXBvc2l0aW9uLCB5PXNjb3JlKSwgYWxwaGEgPSAwLjc1LCBwb3NpdGlvbj1qaXR0ZXIxKSArIHNjYWxlX2NvbG9yX2Rpc3RpbGxlcihwYWxldHRlID0gIlNwZWN0cmFsIikKI2luIGluIGdlb21fdmlvbGluKGFlcygpKSAtPiBjb2xvdXIgPSBoeWRybzEKCgojcHRlbl9zX3NwcmVhZCA8LSBnZ3Bsb3QocHRlbjFfcHJvY193dCwgYWVzKHk9c2NvcmUsIHg9cG9zaXRpb24pKSArIGdlb21fcG9pbnQoZGF0YT1zdWJzZXQocHRlbjFfcHJvY193dCwgc3RhcnQ9PSAiUyIpKSArIHhsYWIoIlBvc2l0aW9uIGluIFBURU4iKSArIGdndGl0bGUoIlNlcmluZSB2YXJpYW50IGFidW5kYW5jZSBzY29yZXMiKQojcHRlbl9zX3NwcmVhZDFfb2xkIDwtIGdncGxvdChwdGVuMV9wcm9jX3d0LCBhZXMoeT1zY29yZSwgeD1zdGFydCkpICsgZ2VvbV92aW9saW4oZHJhd19xdWFudGlsZXM9YygwLjUpLCBkYXRhPXN1YnNldChwdGVuMV9wcm9jX3d0LCBzdGFydD09ICJTIiksIGFlcyhncm91cD1mYWN0b3IocG9zaXRpb24pKSkgKyB4bGFiKCJQb3NpdGlvbiBpbiBQVEVOIikgKyBnZ3RpdGxlKCJTZXJpbmUgdmFyaWFudCBhYnVuZGFuY2Ugc2NvcmVzIikKcHRlbl9zX3NwcmVhZDEgPC0gZ2dwbG90KHB0ZW4xX3Byb2Nfd3QsIGFlcyh5PXNjb3JlLCB4PWZhY3Rvcihwb3NpdGlvbiksIGNvbG91ciA9IGVuZCkpICsgZ2VvbV92aW9saW4oZHJhd19xdWFudGlsZXM9YygwLjUpLCBkYXRhPXN1YnNldChwdGVuMV9wcm9jX3d0LCBzdGFydD09ICJTIiksIGFlcyhncm91cD1mYWN0b3IocG9zaXRpb24pKSwgc2NhbGUgPSAid2lkdGgiKSArIHhsYWIoIlBvc2l0aW9uIGluIFBURU4iKSArIGdndGl0bGUoIlNlcmluZSB2YXJpYW50IGFidW5kYW5jZSBzY29yZXMiKSsgZ2VvbV9wb2ludChkYXRhPXN1YnNldChwdGVuMV9wcm9jX3d0LCBzdGFydD09ICJTIiksIGFlcyh4PWZhY3Rvcihwb3NpdGlvbiksIHk9c2NvcmUpLCBhbHBoYSA9IDAuODUsIHBvc2l0aW9uPWppdHRlcjIpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz10d2VudHlfY29sb3IpCnB0ZW5fc19hYSA8LSBnZ3Bsb3QocHRlbjFfcHJvY193dCwgYWVzKHk9c2NvcmUsIHg9ZW5kLCBjb2xvdXIgPSBlbmQpKSArIGdlb21fdmlvbGluKGRyYXdfcXVhbnRpbGVzPWMoMC41KSwgZGF0YT1zdWJzZXQocHRlbjFfcHJvY193dCwgc3RhcnQ9PSAiUyIpLCBhZXMoZ3JvdXA9ZW5kKSwgc2NhbGUgPSAid2lkdGgiKSArIHhsYWIoIkFtaW5vIGFjaWQiKSArIGdndGl0bGUoIlNlcmluZSB2YXJpYW50IGFidW5kYW5jZSBzY29yZXMiKSsgZ2VvbV9wb2ludChkYXRhPXN1YnNldChwdGVuMV9wcm9jX3d0LCBzdGFydD09ICJTIiksIGFlcyh4PWVuZCwgeT1zY29yZSksIGFscGhhID0gMC43NSwgcG9zaXRpb249aml0dGVyMSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPXR3ZW50eV9jb2xvcikKCnB0ZW5fc19oeWRyb2RpZmYgPC0gZ2dwbG90KHB0ZW4xX3Byb2Nfd3QsIGFlcyh5PXNjb3JlLCB4PWZhY3Rvcihwb3NpdGlvbiksIGNvbG91ciA9IChoeWRybzItaHlkcm8xKSkpICsgZ2VvbV92aW9saW4oZHJhd19xdWFudGlsZXM9YygwLjUpLCBkYXRhPXN1YnNldChwdGVuMV9wcm9jX3d0LCBzdGFydD09ICJTIiksIGFlcyhncm91cD1mYWN0b3IocG9zaXRpb24pKSwgc2NhbGUgPSAid2lkdGgiKSArIHhsYWIoIlBvc2l0aW9uIGluIFBURU4iKSArIGdndGl0bGUoIlNlcmluZSB2YXJpYW50IGFidW5kYW5jZSBzY29yZXMgdy8gaHlkcm9waG9iaWNpdHkgY2hhbmdlIikrIGdlb21fcG9pbnQoZGF0YT1zdWJzZXQocHRlbjFfcHJvY193dCwgc3RhcnQ9PSAiUyIpLCBhZXMoeD1mYWN0b3IocG9zaXRpb24pLCB5PXNjb3JlKSwgYWxwaGEgPSAwLjg1LCBwb3NpdGlvbj1qaXR0ZXIyKSArIHNjYWxlX2NvbG9yX2Rpc3RpbGxlcihwYWxldHRlID0gIlNwZWN0cmFsIikKI2dyYXBoaW5nIGFidW5kYW5jZSB2cyBjaGFuZ2UgaW4gaHlkcm9waG9iaWNpdHkKcHRlbl9zX2hoX2h5ZHJvZGlmZiA8LSBnZ3Bsb3QocHRlbjFfcHJvY193dCwgYWVzKHk9c2NvcmUsIHg9ZmFjdG9yKGh5ZHJvMi1oeWRybzEpLCBjb2xvdXIgPSAoaHlkcm8yLWh5ZHJvMSkpKSArIGdlb21fdmlvbGluKGRyYXdfcXVhbnRpbGVzPWMoMC41KSwgZGF0YT1zdWJzZXQocHRlbjFfcHJvY193dCwgc3RhcnQ9PSAiUyIpLCBhZXMoZ3JvdXA9ZmFjdG9yKGh5ZHJvMi1oeWRybzEpKSwgc2NhbGUgPSAid2lkdGgiKSArIHhsYWIoIkNoYW5nZSBpbiBoeWRyb3Bob2JpY2l0eSIpICsgZ2d0aXRsZSgiU2VyaW5lIHZhcmlhbnQgYWJ1bmRhbmNlIHNjb3JlcyIpKyBnZW9tX3BvaW50KGRhdGE9c3Vic2V0KHB0ZW4xX3Byb2Nfd3QsIHN0YXJ0PT0gIlMiKSwgYWVzKHg9ZmFjdG9yKGh5ZHJvMi1oeWRybzEpLCB5PXNjb3JlKSwgYWxwaGEgPSAwLjc1LCBwb3NpdGlvbj1qaXR0ZXIxKQojcHRlbl9zX2FhX2h5ZHJvZGlmZiA8LSBnZ3Bsb3QocHRlbjFfcHJvY193dCwgYWVzKHk9c2NvcmUsIHg9ZW5kLCBjb2xvdXIgPSAoaHlkcm8yLWh5ZHJvMSkpKSArIGdlb21fdmlvbGluKGRyYXdfcXVhbnRpbGVzPWMoMC41KSwgZGF0YT1zdWJzZXQocHRlbjFfcHJvY193dCwgc3RhcnQ9PSAiUyIpLCBhZXMoZ3JvdXA9ZW5kKSwgc2NhbGUgPSAid2lkdGgiKSArIHhsYWIoIkFtaW5vIGFjaWQiKSArIGdndGl0bGUoIlNlcmluZSB2YXJpYW50IGFidW5kYW5jZSBzY29yZXMiKSsgZ2VvbV9wb2ludChkYXRhPXN1YnNldChwdGVuMV9wcm9jX3d0LCBzdGFydD09ICJTIiksIGFlcyh4PWVuZCwgeT1zY29yZSksIGFscGhhID0gMC43NSwgcG9zaXRpb249aml0dGVyMSkKI3B0ZW5fc19hYV92b2xkaWZmIDwtIGdncGxvdChwdGVuMV9wcm9jX3d0LCBhZXMoeT1zY29yZSwgeD1lbmQsIGNvbG91ciA9IHZvbGRpZmYpKSArIGdlb21fdmlvbGluKGRyYXdfcXVhbnRpbGVzPWMoMC41KSwgZGF0YT1zdWJzZXQocHRlbjFfcHJvY193dCwgc3RhcnQ9PSAiUyIpLCBhZXMoZ3JvdXA9ZW5kKSwgc2NhbGUgPSAid2lkdGgiKSArIHhsYWIoIkFtaW5vIGFjaWQiKSArIGdndGl0bGUoIlNlcmluZSB2YXJpYW50IGFidW5kYW5jZSBzY29yZXMiKSsgZ2VvbV9wb2ludChkYXRhPXN1YnNldChwdGVuMV9wcm9jX3d0LCBzdGFydD09ICJTIiksIGFlcyh4PWVuZCwgeT1zY29yZSksIGFscGhhID0gMC43NSwgcG9zaXRpb249aml0dGVyMSkKI3B0ZW5fc19hYV9wb2xkaWZmIDwtIGdncGxvdChwdGVuMV9wcm9jX3d0LCBhZXMoeT1zY29yZSwgeD1lbmQsIGNvbG91ciA9IHBvbGFyaXR5ZGlmZikpICsgZ2VvbV92aW9saW4oZHJhd19xdWFudGlsZXM9YygwLjUpLCBkYXRhPXN1YnNldChwdGVuMV9wcm9jX3d0LCBzdGFydD09ICJTIiksIGFlcyhncm91cD1lbmQpLCBzY2FsZSA9ICJ3aWR0aCIpICsgeGxhYigiQW1pbm8gYWNpZCIpICsgZ2d0aXRsZSgiU2VyaW5lIHZhcmlhbnQgYWJ1bmRhbmNlIHNjb3JlcyIpKyBnZW9tX3BvaW50KGRhdGE9c3Vic2V0KHB0ZW4xX3Byb2Nfd3QsIHN0YXJ0PT0gIlMiKSwgYWVzKHg9ZW5kLCB5PXNjb3JlKSwgYWxwaGEgPSAwLjc1LCBwb3NpdGlvbj1qaXR0ZXIxKQojcHRlbl9zX2FhX3dlaWdodGRpZmYgPC0gZ2dwbG90KHB0ZW4xX3Byb2Nfd3QsIGFlcyh5PXNjb3JlLCB4PWVuZCwgY29sb3VyID0gd2VpZ2h0ZGlmZikpICsgZ2VvbV92aW9saW4oZHJhd19xdWFudGlsZXM9YygwLjUpLCBkYXRhPXN1YnNldChwdGVuMV9wcm9jX3d0LCBzdGFydD09ICJTIiksIGFlcyhncm91cD1lbmQpLCBzY2FsZSA9ICJ3aWR0aCIpICsgeGxhYigiQW1pbm8gYWNpZCIpICsgZ2d0aXRsZSgiU2VyaW5lIHZhcmlhbnQgYWJ1bmRhbmNlIHNjb3JlcyIpKyBnZW9tX3BvaW50KGRhdGE9c3Vic2V0KHB0ZW4xX3Byb2Nfd3QsIHN0YXJ0PT0gIlMiKSwgYWVzKHg9ZW5kLCB5PXNjb3JlKSwgYWxwaGEgPSAwLjc1LCBwb3NpdGlvbj1qaXR0ZXIxKQoKI3NwZWNpZmljIGFtaW5vIGFjaWQgdGVzdHMKIyNwbG90KHB0ZW5fa19zcHJlYWQpCiMjcGxvdChwdGVuX2dfc3ByZWFkKQojI3Bsb3QocHRlbl9jX3NwcmVhZCkKCiMjcGxvdChwdGVuX3Nfc3ByZWFkKQojI3Bsb3QocHRlbl9zX3NwcmVhZDFfb2xkKQoKI3Bsb3QocHRlbl9zX2hoX2h5ZHJvZGlmZikgI3Byb2JhYmx5IG5vdCB2ZXJ5IHVzZWZ1bC4uLiBkb2VzIG5vdCB0YWtlIGludG8gYWNjb3VudCBwb3NpdGlvbiBhbnltb3JlCiMjcGxvdChwdGVuX3NfYWFfaHlkcm9kaWZmKQojI3Bsb3QocHRlbl9zX2FhX3ZvbGRpZmYpCiMjcGxvdChwdGVuX3NfYWFfcG9sZGlmZikKIyNwbG90KHB0ZW5fc19hYV93ZWlnaHRkaWZmKQoKCnBsb3QocHRlbl9jX3NwcmVhZDEpCnBsb3QocHRlbl9jX2FhKQpwbG90KHB0ZW5fY19oeWRyb2RpZmYpCnBsb3QocHRlbl9zX3NwcmVhZDEpCnBsb3QocHRlbl9zX2FhKQpwbG90KHB0ZW5fc19oeWRyb2RpZmYpCnBsb3QocHRlbl9nX3NwcmVhZDEpCnBsb3QocHRlbl9nX2FhKQpwbG90KHB0ZW5fZ19oeWRyb2RpZmYpCnBsb3QocHRlbl9rX3NwcmVhZDEpCnBsb3QocHRlbl9rX2FhKQpgYGAKYGBge3J9CnB0ZW5fYV9zcHJlYWQxIDwtIGdncGxvdChwdGVuMV9wcm9jX3d0LCBhZXMoeT1zY29yZSwgeD1mYWN0b3IocG9zaXRpb24pLCBjb2xvdXIgPSBlbmQpKSArIGdlb21fdmlvbGluKGRyYXdfcXVhbnRpbGVzPWMoMC41KSwgZGF0YT1zdWJzZXQocHRlbjFfcHJvY193dCwgc3RhcnQ9PSAiQSIpLCBhZXMoZ3JvdXA9ZmFjdG9yKHBvc2l0aW9uKSksIHNjYWxlID0gIndpZHRoIikgKyB4bGFiKCJQb3NpdGlvbiBpbiBQVEVOIikgKyBnZ3RpdGxlKCJBbGFuaW5lIHZhcmlhbnQgYWJ1bmRhbmNlIHNjb3JlcyIpKyBnZW9tX3BvaW50KGRhdGE9c3Vic2V0KHB0ZW4xX3Byb2Nfd3QsIHN0YXJ0PT0gIkEiKSwgYWVzKHg9ZmFjdG9yKHBvc2l0aW9uKSwgeT1zY29yZSksIGFscGhhID0gMC44NSwgcG9zaXRpb249aml0dGVyMikgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPXR3ZW50eV9jb2xvcikKcHRlbl9hX2FhIDwtIGdncGxvdChwdGVuMV9wcm9jX3d0LCBhZXMoeT1zY29yZSwgeD1lbmQsIGNvbG91ciA9IGVuZCkpICsgZ2VvbV92aW9saW4oZHJhd19xdWFudGlsZXM9YygwLjUpLCBkYXRhPXN1YnNldChwdGVuMV9wcm9jX3d0LCBzdGFydD09ICJBIiksIGFlcyhncm91cD1lbmQpLCBzY2FsZSA9ICJ3aWR0aCIpICsgeGxhYigiQW1pbm8gYWNpZCIpICsgZ2d0aXRsZSgiQWxhbmluZSB2YXJpYW50IGFidW5kYW5jZSBzY29yZXMiKSsgZ2VvbV9wb2ludChkYXRhPXN1YnNldChwdGVuMV9wcm9jX3d0LCBzdGFydD09ICJBIiksIGFlcyh4PWVuZCwgeT1zY29yZSksIGFscGhhID0gMC43NSwgcG9zaXRpb249aml0dGVyMSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPXR3ZW50eV9jb2xvcikKCnB0ZW5fcl9zcHJlYWQxIDwtIGdncGxvdChwdGVuMV9wcm9jX3d0LCBhZXMoeT1zY29yZSwgeD1mYWN0b3IocG9zaXRpb24pLCBjb2xvdXIgPSBlbmQpKSArIGdlb21fdmlvbGluKGRyYXdfcXVhbnRpbGVzPWMoMC41KSwgZGF0YT1zdWJzZXQocHRlbjFfcHJvY193dCwgc3RhcnQ9PSAiUiIpLCBhZXMoZ3JvdXA9ZmFjdG9yKHBvc2l0aW9uKSksIHNjYWxlID0gIndpZHRoIikgKyB4bGFiKCJQb3NpdGlvbiBpbiBQVEVOIikgKyBnZ3RpdGxlKCJBcmdhbmluZSB2YXJpYW50IGFidW5kYW5jZSBzY29yZXMiKSsgZ2VvbV9wb2ludChkYXRhPXN1YnNldChwdGVuMV9wcm9jX3d0LCBzdGFydD09ICJSIiksIGFlcyh4PWZhY3Rvcihwb3NpdGlvbiksIHk9c2NvcmUpLCBhbHBoYSA9IDAuODUsIHBvc2l0aW9uPWppdHRlcjIpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz10d2VudHlfY29sb3IpCnB0ZW5fcl9hYSA8LSBnZ3Bsb3QocHRlbjFfcHJvY193dCwgYWVzKHk9c2NvcmUsIHg9ZW5kLCBjb2xvdXIgPSBlbmQpKSArIGdlb21fdmlvbGluKGRyYXdfcXVhbnRpbGVzPWMoMC41KSwgZGF0YT1zdWJzZXQocHRlbjFfcHJvY193dCwgc3RhcnQ9PSAiUiIpLCBhZXMoZ3JvdXA9ZW5kKSwgc2NhbGUgPSAid2lkdGgiKSArIHhsYWIoIkFtaW5vIGFjaWQiKSArIGdndGl0bGUoIkFyZ2FuaW5lIHZhcmlhbnQgYWJ1bmRhbmNlIHNjb3JlcyIpKyBnZW9tX3BvaW50KGRhdGE9c3Vic2V0KHB0ZW4xX3Byb2Nfd3QsIHN0YXJ0PT0gIlIiKSwgYWVzKHg9ZW5kLCB5PXNjb3JlKSwgYWxwaGEgPSAwLjc1LCBwb3NpdGlvbj1qaXR0ZXIxKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9dHdlbnR5X2NvbG9yKQoKcHRlbl9uX3NwcmVhZDEgPC0gZ2dwbG90KHB0ZW4xX3Byb2Nfd3QsIGFlcyh5PXNjb3JlLCB4PWZhY3Rvcihwb3NpdGlvbiksIGNvbG91ciA9IGVuZCkpICsgZ2VvbV92aW9saW4oZHJhd19xdWFudGlsZXM9YygwLjUpLCBkYXRhPXN1YnNldChwdGVuMV9wcm9jX3d0LCBzdGFydD09ICJOIiksIGFlcyhncm91cD1mYWN0b3IocG9zaXRpb24pKSwgc2NhbGUgPSAid2lkdGgiKSArIHhsYWIoIlBvc2l0aW9uIGluIFBURU4iKSArIGdndGl0bGUoIkFzcGFyYWdpbmUgdmFyaWFudCBhYnVuZGFuY2Ugc2NvcmVzIikrIGdlb21fcG9pbnQoZGF0YT1zdWJzZXQocHRlbjFfcHJvY193dCwgc3RhcnQ9PSAiTiIpLCBhZXMoeD1mYWN0b3IocG9zaXRpb24pLCB5PXNjb3JlKSwgYWxwaGEgPSAwLjg1LCBwb3NpdGlvbj1qaXR0ZXIyKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9dHdlbnR5X2NvbG9yKQpwdGVuX25fYWEgPC0gZ2dwbG90KHB0ZW4xX3Byb2Nfd3QsIGFlcyh5PXNjb3JlLCB4PWVuZCwgY29sb3VyID0gZW5kKSkgKyBnZW9tX3Zpb2xpbihkcmF3X3F1YW50aWxlcz1jKDAuNSksIGRhdGE9c3Vic2V0KHB0ZW4xX3Byb2Nfd3QsIHN0YXJ0PT0gIk4iKSwgYWVzKGdyb3VwPWVuZCksIHNjYWxlID0gIndpZHRoIikgKyB4bGFiKCJBbWlubyBhY2lkIikgKyBnZ3RpdGxlKCJBc3BhcmFnaW5lIHZhcmlhbnQgYWJ1bmRhbmNlIHNjb3JlcyIpKyBnZW9tX3BvaW50KGRhdGE9c3Vic2V0KHB0ZW4xX3Byb2Nfd3QsIHN0YXJ0PT0gIk4iKSwgYWVzKHg9ZW5kLCB5PXNjb3JlKSwgYWxwaGEgPSAwLjc1LCBwb3NpdGlvbj1qaXR0ZXIxKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9dHdlbnR5X2NvbG9yKQoKcHRlbl9kX3NwcmVhZDEgPC0gZ2dwbG90KHB0ZW4xX3Byb2Nfd3QsIGFlcyh5PXNjb3JlLCB4PWZhY3Rvcihwb3NpdGlvbiksIGNvbG91ciA9IGVuZCkpICsgZ2VvbV92aW9saW4oZHJhd19xdWFudGlsZXM9YygwLjUpLCBkYXRhPXN1YnNldChwdGVuMV9wcm9jX3d0LCBzdGFydD09ICJEIiksIGFlcyhncm91cD1mYWN0b3IocG9zaXRpb24pKSwgc2NhbGUgPSAid2lkdGgiKSArIHhsYWIoIlBvc2l0aW9uIGluIFBURU4iKSArIGdndGl0bGUoIkFzcGFydGljIEFjaWQgdmFyaWFudCBhYnVuZGFuY2Ugc2NvcmVzIikrIGdlb21fcG9pbnQoZGF0YT1zdWJzZXQocHRlbjFfcHJvY193dCwgc3RhcnQ9PSAiRCIpLCBhZXMoeD1mYWN0b3IocG9zaXRpb24pLCB5PXNjb3JlKSwgYWxwaGEgPSAwLjg1LCBwb3NpdGlvbj1qaXR0ZXIyKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9dHdlbnR5X2NvbG9yKQpwdGVuX2RfYWEgPC0gZ2dwbG90KHB0ZW4xX3Byb2Nfd3QsIGFlcyh5PXNjb3JlLCB4PWVuZCwgY29sb3VyID0gZW5kKSkgKyBnZW9tX3Zpb2xpbihkcmF3X3F1YW50aWxlcz1jKDAuNSksIGRhdGE9c3Vic2V0KHB0ZW4xX3Byb2Nfd3QsIHN0YXJ0PT0gIkQiKSwgYWVzKGdyb3VwPWVuZCksIHNjYWxlID0gIndpZHRoIikgKyB4bGFiKCJBbWlubyBhY2lkIikgKyBnZ3RpdGxlKCJBc3BhcnRpYyBBY2lkIHZhcmlhbnQgYWJ1bmRhbmNlIHNjb3JlcyIpKyBnZW9tX3BvaW50KGRhdGE9c3Vic2V0KHB0ZW4xX3Byb2Nfd3QsIHN0YXJ0PT0gIkQiKSwgYWVzKHg9ZW5kLCB5PXNjb3JlKSwgYWxwaGEgPSAwLjc1LCBwb3NpdGlvbj1qaXR0ZXIxKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9dHdlbnR5X2NvbG9yKQoKCnBsb3QocHRlbl9hX3NwcmVhZDEpCnBsb3QocHRlbl9hX2FhKQpwbG90KHB0ZW5fcl9zcHJlYWQxKQpwbG90KHB0ZW5fcl9hYSkKcGxvdChwdGVuX25fc3ByZWFkMSkKcGxvdChwdGVuX25fYWEpCnBsb3QocHRlbl9kX3NwcmVhZDEpCnBsb3QocHRlbl9kX2FhKQoKCmBgYAoKYGBge3IgaW5jbHVkZT1GQUxTRX0KI29uIGhvbGQsIGNyZWF0aW9uIG9mIGFtaW5vIGFjaWQgZGF0YWZyYW1lIHRvIHBsb3QgYWJ1bmRhbmNlIHNjb3JlcyBhZ2FpbnN0Cm5hbWUgPC0gYygnQWxhJywgJ0FyZycsICdBc24nLCAnQXNwJywgJ0N5cycsICdHbHUnLCAnR2xuJywgJ0dseScsICdIaXMnLCAnSWxlJywgJ0xldScsICdMeXMnLCAnTWV0JywgJ1BoZScsICdQcm8nLCAnU2VyJywgJ1RocicsICdUcnAnLCAnVHlyJywgJ1ZhbCcpCnF1YWxpdHkgPC0gYygnSHlkcm9waG9iaWMnLCAnQmFzaWMnLCAnUG9sYXIgTmV1dHJhbCcsICdBY2lkaWMnLCAnUG9sYXIgTmV1dHJhbCcsICdBY2lkaWMnLCAnUG9sYXIgTmV1dHJhbCcsICdHbHljaW5lJywgJ0Jhc2ljJywgJ0h5ZHJvcGhvYmljJywgJ0h5ZHJvcGhvYmljJywgJ0Jhc2ljJywgJ0h5ZHJvcGhvYmljJywgJ0h5ZHJvcGhvYmljJywgJ0h5ZHJvcGhvYmljJywgJ1BvbGFyIE5ldXRyYWwnLCAnUG9sYXIgTmV1dHJhbCcsICdIeWRyb3Bob2JpYycsICdIeWRyb3Bob2JpYycsICdIeWRyb3Bob2JpYycpCiNhYnVuZGFuY2UgPC0gZ2V0IGJldHRlciBzY2FsZQphYnVuZGFuY2UgPC0gYygwLjA4ODQsIDAuMDU3LCAwLjA0MTcsIDAuMDUzOSwgMC4wMTI0LCAwLjA2MjQsIDAuMDM4MiwgMC4wNzAzLCAwLjAyMjAsIDAuMDU5NSwgMC4wOTk0LCAwLjA1MjcsIDAuMDIzNywgMC4wNCwgMC4wNDcxLCAwLjA2NzIsIDAuMDU0MywgMC4wMTIxLCAwLjAzLCAwLjA2NzcpCiNpc29lbGVjdHJpYyBwb2ludCA8LSB1bmtub3duIHNvdXJjZSAobmNiaSkKaXNvZWxlY3RyaWMgPC0gYyg2LCAxMC44LCA1LjQsIDMsIDUsIDMuMiwgNS43LCA2LCA3LjYsIDYsIDYsIDkuNywgNS43LCA1LjUsIDYuMywgNS43LCA1LjYsIDUuOSwgNS43LCA2LjApCmhwX2tfZCA8LSBjKDEuOCwgLTQuNSwgLTMuNSwgLTMuNSwgMi41LCAtMy41LCAtMy41LCAtMC40LCAtMy4yLCA0LjUsIDMuOCwgLTMuOSwgMS45LCAyLjgsIC0xLjYsIC0wLjgsIC0wLjcsIC0wLjksIC0xLjMsIDQuMikKaHBfamFuaW4gPC1jKDAuMywgLTEuNCwgLTAuNSwgLTAuNiwgMC45LCAtMC43LCAtMC43LCAwLjMsIC0wLjEsIDAuNywgMC41LCAtMS44LCAwLjQsIDAuNSwgLTAuMywgLTAuMSwgLTAuMiwgMC4zLCAtMC40LCAwLjYpCiNNb25lcmEgZXQgYWwuLCBKLiBQcm90ZWluIFNjaSAocHJvICgtNDYpIG1heSBiZSBza2V0Y2gpCmhwX3BoNyA8LSBjKDQxLCAtMTQsIC0yOCwgLTU1LCA0OSwgLTMxLCAtMTAsIDAsIDgsIDk5LCA5NywgLTIzLCA3NCwgMTAwLCAtNDYsIC01LCAxMywgOTcsIDYzLCA3NikKaF9ib25kcyA8LSBjKDAsIDcsIDUsIDQsIDAsIDQsIDUsIDAsIDMsIDAsIDAsIDMsIDAsIDAsIDAsIDMsIDMsIDEsIDMsIDApCm1vbF93ZWlnaHQgPC1jKDcxLCAxNTYsIDExNCwgMTE1LCAxMDMsIDEyOSwgMTI4LCA1NywgMTM3LCAxMTMsIDExMywgMTI4LCAxMzEsIDE0NywgOTcsIDg3LCAxMDEsIDE4NiwgMTYzLCA5OSkKCmFtaW5vX2FjaWRzLmRhdGEgPC0gZGF0YS5mcmFtZShuYW1lLCBxdWFsaXR5LCBhYnVuZGFuY2UsIGlzb2VsZWN0cmljLCBocF9rX2QsIGhwX2phbmluLCBocF9waDcsIGhfYm9uZHMsIG1vbF93ZWlnaHQpCgpgYGAKCmBgYHtyIGluY2x1ZGU9RkFMU0V9CmltZyA9IHJlYWRJbWFnZSgiL1VzZXJzL2dvMmFseXNzYS9EZXNrdG9wL2RlbnNpdHlfcGxvdHMucG5nIikKZGlzcGxheShpbWcsIG1ldGhvZCA9ICJyYXN0ZXIiKQpgYGAKVkFNUC1zZXEgYWJ1bmRhbmNlIHNjb3JlIGRlbnNpdHkgcGxvdHMgZm9yIFBURU4gKHRvcCkgYW5kIFRQTVQgKGJvdHRvbSkgbm9uc2Vuc2UgdmFyaWFudHMgKGJsdWUgZGFzaGVkIGxpbmUpLCBzeW5vbnltb3VzIHZhcmlhbnRzIChyZWQgZGFzaGVkIGxpbmUpIGFuZCBtaXNzZW5zZSB2YXJpYW50cyAoZmlsbGVkLCBzb2xpZCBsaW5lKS4gVGhlIG1pc3NlbnNlIHZhcmlhbnQgZGVuc2l0aWVzIGFyZSBjb2xvcmVkIGFzIGdyYWRpZW50cyBiZXR3ZWVuIHRoZSBsb3dlc3QgMTAlIG9mIGFidW5kYW5jZSBzY29yZXMgKGJsdWUpLCB0aGUgV1QgYWJ1bmRhbmNlIHNjb3JlICh3aGl0ZSkgYW5kIGFidW5kYW5jZSBzY29yZXMgYWJvdmUgV1QgKHJlZCkuCmBgYHtyfQojSWRlbnRpZnlpbmcgaXRlbXMgaW4gdGFpbCB0byBpbnZlc3RpZ2F0ZQpwdGVuMV9ub25zZW5zZSA8LSBzdWJzZXQocHRlbjFfcHJvYywgY2xhc3MgPT0gIm5vbnNlbnNlIikKdHBtdDFfbm9uc2Vuc2UgPC0gc3Vic2V0KHRwbXQxX3Byb2MsIGNsYXNzID09ICJub25zZW5zZSIpCnB0ZW4xX3N5bm9uIDwtIHN1YnNldChwdGVuMV9wcm9jLCBjbGFzcyA9PSAic3lub255bW91cyIpCnRwbXQxX3N5bm9uIDwtIHN1YnNldCh0cG10MV9wcm9jLCBjbGFzcyA9PSAic3lub255bW91cyIpCgpwdGVuMV9ub19taXNzZW5zZSA8LSBzdWJzZXQocHRlbjFfcHJvYywgY2xhc3MgPT0gInN5bm9ueW1vdXMiIHwgY2xhc3MgPT0gIm5vbnNlbnNlIikKCmdncGxvdChwdGVuMV9ub25zZW5zZSwgYWVzKHg9c2NvcmUpKSArIGdlb21faGlzdG9ncmFtKGJpbndpZHRoPS4wMSwgY29sb3VyPSJibHVlIiwgZmlsbD0id2hpdGUiKSAKIysgZ2VvbV9kZW5zaXR5KCkKZ2dwbG90KHB0ZW4xX3N5bm9uLCBhZXMoeD1zY29yZSkpICsgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGg9LjAxLCBjb2xvdXI9InJlZCIsIGZpbGw9IndoaXRlIikKCmdncGxvdChwdGVuMV9wcm9jX3d0LCBhZXMoeD1zY29yZSkpICsgZ2VvbV9oaXN0b2dyYW0oZGF0YT1zdWJzZXQocHRlbjFfcHJvY193dCxjbGFzcyA9PSAibm9uc2Vuc2UiKSwgZmlsbCA9ICJyZWQiLCBhbHBoYSA9IDAuNSwgYmlud2lkdGg9LjAxKSArIGdlb21faGlzdG9ncmFtKGRhdGE9c3Vic2V0KHB0ZW4xX3Byb2Nfd3QsY2xhc3MgPT0gInN5bm9ueW1vdXMiKSwgZmlsbCA9ICJibHVlIiwgYWxwaGEgPSAwLjUsIGJpbndpZHRoPS4wMSkgKyBnZW9tX2hpc3RvZ3JhbShkYXRhPXN1YnNldChwdGVuMV9wcm9jX3d0LGNsYXNzID09ICJtaXNzZW5zZSIpLCBmaWxsID0gImdyZWVuIiwgYWxwaGEgPSAwLjIsIGJpbndpZHRoPS4wMSkKCmdncGxvdChwdGVuMV9ub19taXNzZW5zZSwgYWVzKHg9c2NvcmUpKSArIGdlb21faGlzdG9ncmFtKGRhdGE9c3Vic2V0KHB0ZW4xX25vX21pc3NlbnNlLGNsYXNzID09ICJub25zZW5zZSIpLCBmaWxsID0gInJlZCIsIGFscGhhID0gMC41LCBiaW53aWR0aD0uMDEpICsgZ2VvbV9oaXN0b2dyYW0oZGF0YT1zdWJzZXQocHRlbjFfbm9fbWlzc2Vuc2UsY2xhc3MgPT0gInN5bm9ueW1vdXMiKSwgZmlsbCA9ICJibHVlIiwgYWxwaGEgPSAwLjUsIGJpbndpZHRoPS4wMSkKCmdncGxvdCh0cG10MV9zeW5vbiwgYWVzKHg9c2NvcmUpKSArIGdlb21faGlzdG9ncmFtKGJpbndpZHRoPS4wMSwgY29sb3VyPSJyZWQiLCBmaWxsPSJ3aGl0ZSIpCmdncGxvdCh0cG10MV9ub25zZW5zZSwgYWVzKHg9c2NvcmUpKSArIGdlb21faGlzdG9ncmFtKGJpbndpZHRoPS4wMSwgY29sb3VyPSJibHVlIiwgZmlsbD0id2hpdGUiKQpgYGAKYGBge3J9CiMwLjU1Cm5vbnNlbnNlX3RhaWwgPC0gc3Vic2V0KHB0ZW4xX25vbnNlbnNlLCBzY29yZSA+IDAuNikKc3lub25fdGFpbCA8LSBzdWJzZXQocHRlbjFfc3lub24sIHNjb3JlIDwgMC42KQpub25zZW5zZV90YWlsJHNlY29uZGFyeV9zdHJ1Y3QgPC0gaWZlbHNlKGlzLm5hKG5vbnNlbnNlX3RhaWwkaGVsaXgpLCAidW5rbm93biIsCiAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShub25zZW5zZV90YWlsJGhlbGl4PT0xLCAiaGVsaXgiLAogICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2Uobm9uc2Vuc2VfdGFpbCRzaGVldD09MSwgInNoZWV0IiwKICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKG5vbnNlbnNlX3RhaWwkaGVsaXg9PTAsICJuZWl0aGVyIiwKICAgICAgICAgICAgICAgICAgICAgICAgInVua25vd24iKSkpKQpzeW5vbl90YWlsJHNlY29uZGFyeV9zdHJ1Y3QgPC0gaWZlbHNlKGlzLm5hKHN5bm9uX3RhaWwkaGVsaXgpLCAidW5rbm93biIsCiAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShzeW5vbl90YWlsJGhlbGl4PT0xLCAiaGVsaXgiLAogICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2Uoc3lub25fdGFpbCRzaGVldD09MSwgInNoZWV0IiwKICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHN5bm9uX3RhaWwkaGVsaXg9PTAsICJuZWl0aGVyIiwKICAgICAgICAgICAgICAgICAgICAgICAgInVua25vd24iKSkpKQoKI2RhdGFbcm93LGNvbHVtbl0Kbl90YWlsIDwtIG5vbnNlbnNlX3RhaWxbLGMoMSwyLDcsMzAsMTI3KV0Kc190YWlsIDwtIHN5bm9uX3RhaWxbLGMoMSwyLDcsMzAsMTI3KV0Kbl90YWlsJGJwX3BvcyA8LSAobl90YWlsJHBvc2l0aW9uLTEpKjMKc190YWlsJGJwX3BvcyA8LSAoc190YWlsJHBvc2l0aW9uLTEpKjMKCm5fdGFpbApzX3RhaWwKYGBgCmBgYHtyfQojanVzdCBpbiBjYXNlIHRoZXJlIGlzIGEgZGlzY2VybmlibGUgcGF0dGVybgpzX3RhaWxfcG9zIDwtIGdncGxvdChzX3RhaWwsIGFlcyh4PXBvc2l0aW9uLCB5PXNjb3JlLCBjb2xvdXI9c2Vjb25kYXJ5X3N0cnVjdCkpKyBnZW9tX3BvaW50KHNpemU9LjMpICsgc2NhbGVfeF9jb250aW51b3VzKG1pbm9yX2JyZWFrcyA9IHNlcSgwLCA0MDUsIDUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9YygiI0ZGNDg0OCIsICIjMDBDODUzIiwgIiM1NzU3RkYiLCAiI0E5QTlBOSIpKSAreWxhYigiVkFNUC1zZXEgc2NvcmUiKSt4bGFiKCJQb3NpdGlvbiBpbiBQVEVOIikrbGFicyhjb2xvdXI9IlNlY29uZGFyeSBTdHJ1Y3R1cmUiKStnZ3RpdGxlKCJQVEVOIHN5bm9ueW1vdXMgdmFyaWFudCB0YWlsIHNjb3JlcyBpbiByZWxhdGlvbiB0byBwcm90ZWluIHN0cnVjdHVyZSIpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0PTQ3LCBjb2xvcj0iYmxhY2siLCBzaXplPS4xKSArIGdlb21fdmxpbmUoeGludGVyY2VwdD03OCwgY29sb3I9ImJsYWNrIiwgc2l6ZT0uMSkgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9MTIyLjUsIGNvbG9yPSJibGFjayIsIHNpemU9LjEpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0PTE0MCwgY29sb3I9ImJsYWNrIiwgc2l6ZT0uMSkgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9MTY1LCBjb2xvcj0iYmxhY2siLCBzaXplPS4xKSArIGdlb21fdmxpbmUoeGludGVyY2VwdD0xOTQsIGNvbG9yPSJibGFjayIsIHNpemU9LjEpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0PTIwOSwgY29sb3I9ImJsYWNrIiwgc2l6ZT0uMSkKcGxvdChzX3RhaWxfcG9zKQoKI2hlbHAgdmlzdWFsaXppbmcgTk1EIHJ1bGVzCm5fdGFpbF9wb3MgPC0gZ2dwbG90KG5fdGFpbCwgYWVzKHg9cG9zaXRpb24sIHk9c2NvcmUsIGNvbG91cj1zZWNvbmRhcnlfc3RydWN0KSkrIGdlb21fcG9pbnQoc2l6ZT0uMykgKyBzY2FsZV94X2NvbnRpbnVvdXMobWlub3JfYnJlYWtzID0gc2VxKDAsIDQwNSwgNSkpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jKCIjRkY0ODQ4IiwgIiMwMEM4NTMiLCAiIzU3NTdGRiIsICIjQTlBOUE5IikpICt5bGFiKCJWQU1QLXNlcSBzY29yZSIpK3hsYWIoIlBvc2l0aW9uIGluIFBURU4iKStsYWJzKGNvbG91cj0iU2Vjb25kYXJ5IFN0cnVjdHVyZSIpK2dndGl0bGUoIlBURU4gbm9uc2Vuc2UgdmFyaWFudCB0YWlsIHNjb3JlcyBpbiByZWxhdGlvbiB0byBwcm90ZWluIHN0cnVjdHVyZSIpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0PTQ3LCBjb2xvcj0iYmxhY2siLCBzaXplPS4xKSArIGdlb21fdmxpbmUoeGludGVyY2VwdD03OCwgY29sb3I9ImJsYWNrIiwgc2l6ZT0uMSkgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9MTIyLjUsIGNvbG9yPSJibGFjayIsIHNpemU9LjEpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0PTE0MCwgY29sb3I9ImJsYWNrIiwgc2l6ZT0uMSkgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9MTY1LCBjb2xvcj0iYmxhY2siLCBzaXplPS4xKSArIGdlb21fdmxpbmUoeGludGVyY2VwdD0xOTQsIGNvbG9yPSJibGFjayIsIHNpemU9LjEpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0PTIwOSwgY29sb3I9ImJsYWNrIiwgc2l6ZT0uMSkKcGxvdChuX3RhaWxfcG9zKQpgYGAKCmBgYHtyIGluY2x1ZGU9RkFMU0V9CnNfdGFpbCRwcm9iX0FHX0dUIDwtIGMoMCwgMS82LCAxLzIsIDAsIDEvMiwgMS82KQpzX3RhaWwkcHJvYl90aXR2IDwtIGMoMCwgMi8zLCAyLzMsIDAsIDIvMywgMS8zKQpnZ3Bsb3Qobl90YWlsLCBhZXMoeD1wb3NpdGlvbix5PXNjb3JlKSkgKyBnZW9tX3BvaW50KCkgKyBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iKQpnZ3Bsb3Qoc190YWlsLCBhZXMoeD1wcm9iX3RpdHYseT1zY29yZSkpICsgZ2VvbV9wb2ludCgpICsgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikKZ2dwbG90KHNfdGFpbCwgYWVzKHk9cHJvYl90aXR2LHg9c2NvcmUpKSArIGdlb21fcG9pbnQoKSArIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIpCnJzcSA8LSBmdW5jdGlvbiAoeCwgeSkgY29yKHgsIHkpXjIKbl9yc3EgPC0gcnNxKG5fdGFpbCRwb3NpdGlvbiwgc190YWlsJHNjb3JlKQpzX3JzcSA8LSByc3Eoc190YWlsJHByb2JfdGl0diwgc190YWlsJHNjb3JlKQpuX3JzcQpzX3JzcQojbm8gcmVsYXRpb25zaGlwLi4uCmBgYAoKYGBge3IgaW5jbHVkZT1GQUxTRX0KIyBwdGVuMV9wcm9jX3d0JHNlY29uZGFyeV9zdHJ1Y3QgPC0gaWZlbHNlKGlzLm5hKHB0ZW4xX3Byb2Nfd3QkaGVsaXgpLCAidW5rbm93biIsCiMgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHB0ZW4xX3Byb2Nfd3QkaGVsaXg9PTEsICJoZWxpeCIsCiMgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHB0ZW4xX3Byb2Nfd3Qkc2hlZXQ9PTEsICJzaGVldCIsCiMgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHB0ZW4xX3Byb2Nfd3QkaGVsaXg9PTAsICJuZWl0aGVyIiwKIyAgICAgICAgICAgICAgICAgICAgICAgICAidW5rbm93biIpKSkpCgojc3RhcnQgcG9zaXRpb24gd2l0aGluIHB0ZW4gZ2VuZQojIG5fdGFpbCRzX3BvcyA8LSBpZmVsc2UoKG5fdGFpbCRicF9wb3NfY3VtKT5lMSwgKAojICAgaWZlbHNlKChuX3RhaWwkYnBfcG9zX2N1bSkgPiAoZTErZTIpLCAoCiMgICAgIGlmZWxzZSgobl90YWlsJGJwX3Bvc19jdW0pID4gKGUxK2UyK2UzKSwgKAojICAgICAgIGlmZWxzZSgobl90YWlsJGJwX3Bvc19jdW0pID4gKGUxK2UyK2UzKSwgKAojICAgICAgIAojICAgICAgICksIChuX3RhaWwkYnBfcG9zX2N1bStlNF9zKSkKIyAgICAgKSwgKG5fdGFpbCRicF9wb3NfY3VtK2UzX3MpKQojICAgKSwgKG5fdGFpbCRicF9wb3NfY3VtK2UyX3MpKQojICksIChuX3RhaWwkYnBfcG9zX2N1bStlMV9zKSkKCiNlbmQgcG9zaXRpb24gd2l0aGluIHB0ZW4gZ2VuZQoKI3dpdGhpbiAyIGFtaW5vIGFjaWRzIG9mIGp1bmN0aW9uCgoKIyAjZTFfcyBpcyB0aGUgZmlyc3QgYnAgb2YgdGhlIGZpcnN0IGV4b24KIyBlMV9zID0gODk2MjQyMjcKIyAjZTFfZSBpcyB0aGUgbGFzdCBicCBvZiB0aGUgZmlyc3QgZXhvbiwgCiMgZTFfZSA9IDg5NjI0MzA1CiMgI2UxIGlzIGxlbmd0aCBpbiBicAojIGVsID0gNzkKIyBlMiA9IDg1CiMgZTMgPSA0NQojIGU0ID0gNDQKIyBlNSA9IDIzOQojIGU2ID0gMTQyCiMgZTcgPSAxNjcKIyBlOCA9IDIyNQojIGU5ID0gMTg2CiMgZTJfcyA9IDg5NjUzNzgyCiMgZTJfZSA9IDg5NjUzODY2CiMgZTNfcyA9IDg5Njg1MjcwCQojIGUzX2UgPSA4OTY4NTMxNAkKIyBlNF9zID0gODk2OTA4MDMKIyBlNF9lID0gODk2OTA4NDYKIyBlNV9zID0gODk2OTI3NzAJCiMgZTVfZSA9IDg5NjkzMDA4CiMgZTZfcyA9IDg5NzExODc1CQojIGU2X2UgPSA4OTcxMjAxNgkKIyBlN19zID0gODk3MTc2MTAJCiMgZTdfZSA9IDg5NzE3Nzc2CQojIGU4X3MgPSA4OTcyMDY1MQkKIyBlOF9lID0gODk3MjA4NzUJCiMgZTlfcyA9IDg5NzI1MDQ0CiMgZTlfZSA9IDg5NzI1MjI5CmBgYApgYGB7ciBpbmNsdWRlPUZBTFNFfQoKZ3NfbHMoKQp0cG10X3J1ZGRsZSA8LSBnc190aXRsZSgiVFBNVF9ydWRkbGUiKQp0cG10X3JlYWQgPC0gZ3NfcmVhZChzcz10cG10X3J1ZGRsZSwgd3MgPSAicnVkZGxlX3RwbXRfdmFyaWFudHMiKQp0cG10X3J1ZGRsZV9kYXRhIDwtIGFzLmRhdGEuZnJhbWUodHBtdF9yZWFkKQpgYGAKYGBge3J9CiNyZXZlcnNpbmcgZGF0YSB0byBmaXQgdHBtdDFfZGF0YQpyZXZlciA8LSBmdW5jdGlvbihkZj10cG10X3J1ZGRsZV9kYXRhKXtkZjwtZGZbZGltKGRmKVsxXToxLF19CnRwbXRfcnVkZGxlX2RhdGFfcmV2ID0gcmV2ZXIodHBtdF9ydWRkbGVfZGF0YSkKCiNjcmVhdGluZyB2YXJpYW50IGNvbHVtbiwgZXF1aXYgdG8gdHBtdDFfZGF0YSdzCnRwbXRfcnVkZGxlX2RhdGFfcmV2JHZhcmlhbnQgPC0gZG8uY2FsbChwYXN0ZSwgYyh0cG10X3J1ZGRsZV9kYXRhX3JldltjKDUsMjQsNildLCBzZXA9IiIpKQoKI21ha2luZyBib3RoIHRhYmxlcyBzbWFsbGVyCnRwbXRfZXNzZW50aWFsIDwtIHRwbXRfcnVkZGxlX2RhdGFfcmV2WyxjKDIsMyw0LDUsNiwxNywxOSwyNCwyNywyOCwyOSwzMCwzMSwzMiwzMywzNCwzNSw3Niw3Nyw3OCwxMzcpXQp0cG10MV9wcm9jX2VzcyA8LSB0cG10MV9wcm9jX3d0WyxjKDEsMiwzLDUsNiw3LDMwLDMyLDgwKV0KCiNtZXJnaW5nIHRhYmxlcyB3aXRoIHZhcmlhbnQgbmFtZQp0cG10X21lcmdlIDwtIG1lcmdlKHRwbXQxX3Byb2NfZXNzLCB0cG10X2Vzc2VudGlhbCwgYnk9InZhcmlhbnQiKQoKI2NvbXBhcmluZyBhYnVuZGFuY2Ugc2NvcmVzIHdpdGggdmFyaW91cyBzY29yZXMgaW4gZGJOU0ZQIChjb250YWlucyBhbm5vdGF0aW9ucyBvZiBhbGwgcG90ZW50aWFsIG5vbi1zeW5vbnltb3VzIHNpbmdsZS1udWNsZW90aWRlIHZhcmlhbnRzIChuc1NOVnMpIGluIHRoZSBodW1hbiBnZW5vbWUpCnRwbXRfY29yMSA8LSBnZ3Bsb3QodHBtdF9tZXJnZSwgYWVzKHg9c2NvcmUsIHk9YXMubnVtZXJpYyhTSUZUX3Njb3JlKSkpKyBnZW9tX3BvaW50KGFscGhhID0gMC4yKSArIHhsYWIoIlZBTVAtc2VxIHNjb3JlIikreWxhYigiU0lGVCBzY29yZSIpK2dndGl0bGUoIjEiKQp0cG10X2NvcjEuNSA8LSBnZ3Bsb3QodHBtdF9tZXJnZSwgYWVzKHg9c2NvcmUsIHk9YXMubnVtZXJpYyhTSUZUX2NvbnZlcnRlZF9yYW5rc2NvcmUpKSkrIGdlb21fcG9pbnQoYWxwaGEgPSAwLjIpICsgeGxhYigiVkFNUC1zZXEgc2NvcmUiKSt5bGFiKCJTSUZUIGNvbnZlcnRlZCByYW5rc2NvcmUiKStnZ3RpdGxlKCIxLjUiKQp0cG10X2NvcjUgPC0gZ2dwbG90KHRwbXRfbWVyZ2UsIGFlcyh4PXNjb3JlLCB5PUNBRERfcmF3X3JhbmtzY29yZSkpKyBnZW9tX3BvaW50KGFscGhhID0gMC4yKSArIHhsYWIoIlZBTVAtc2VxIHNjb3JlIikreWxhYigiQ0FERCByYXcgcmFua3Njb3JlIikrZ2d0aXRsZSgiNSIpCnRwbXRfY29yMiA8LSBnZ3Bsb3QodHBtdF9tZXJnZSwgYWVzKHg9c2NvcmUsIHk9YXMubnVtZXJpYyhQb2x5cGhlbjJfSERJVl9zY29yZSkpKSsgZ2VvbV9wb2ludChhbHBoYSA9IDAuMikgKyB4bGFiKCJWQU1QLXNlcSBzY29yZSIpK3lsYWIoIlBvbHlwaGVuMiBIRElWIHNjb3JlIikrZ2d0aXRsZSgiMiIpCnRwbXRfY29yMyA8LSBnZ3Bsb3QodHBtdF9tZXJnZSwgYWVzKHg9c2NvcmUsIHk9YXMubnVtZXJpYyhQb2x5cGhlbjJfSFZBUl9zY29yZSkpKSsgZ2VvbV9wb2ludChhbHBoYSA9IDAuMikgKyB4bGFiKCJWQU1QLXNlcSBzY29yZSIpK3lsYWIoIlBvbHlwaGVuMiBIVkFSIHNjb3JlIikrZ2d0aXRsZSgiMyIpCnRwbXRfY29yMi41IDwtIGdncGxvdCh0cG10X21lcmdlLCBhZXMoeD1zY29yZSwgeT1hcy5udW1lcmljKFBvbHlwaGVuMl9IRElWX3JhbmtzY29yZSkpKSsgZ2VvbV9wb2ludChhbHBoYSA9IDAuMikgKyB4bGFiKCJWQU1QLXNlcSBzY29yZSIpK3lsYWIoIlBvbHlwaGVuMiBIRElWIHJhbmtzY29yZSIpK2dndGl0bGUoIjIuNSIpCnRwbXRfY29yMy41IDwtIGdncGxvdCh0cG10X21lcmdlLCBhZXMoeD1zY29yZSwgeT1hcy5udW1lcmljKFBvbHlwaGVuMl9IVkFSX3JhbmtzY29yZSkpKSsgZ2VvbV9wb2ludChhbHBoYSA9IDAuMikgKyB4bGFiKCJWQU1QLXNlcSBzY29yZSIpK3lsYWIoIlBvbHlwaGVuMiBIVkFSIHJhbmtzY29yZSIpK2dndGl0bGUoIjMuNSIpCgojQ0FERF9waHJlZCBub3Qgd29ydGgKCiNwbG90KHRwbXRfY29yNSkKI3Bsb3QodHBtdF9jb3IxKQojcGxvdCh0cG10X2NvcjEuNSkKcGxvdCh0cG10X2NvcjIpCnBsb3QodHBtdF9jb3IzKQpwbG90KHRwbXRfY29yMi41KQpwbG90KHRwbXRfY29yMy41KQpgYGAKYGBge3J9ClRQTVRfYWJ1bl9DQUREIDwtIGdncGxvdCh0cG10X21lcmdlLCBhZXMoeD1hYnVuZGFuY2VfY2xhc3MsIHk9Q0FERF9yYXdfcmFua3Njb3JlKSkgKyBnZW9tX3Zpb2xpbihkcmF3X3F1YW50aWxlcyA9IGMoIDAuNSkpK3lsYWIoIkNBREQgcmF3IHJhbmtzY29yZSIpK3hsYWIoIkFidW5kYW5jZSBDbGFzcyIpCnBsb3QoVFBNVF9hYnVuX0NBREQpCgpUUE1UX2FidW5fU0lGVF9jb252IDwtIGdncGxvdCh0cG10X21lcmdlLCBhZXMoeD1hYnVuZGFuY2VfY2xhc3MsIHk9YXMubnVtZXJpYyhTSUZUX2NvbnZlcnRlZF9yYW5rc2NvcmUpKSkgKyBnZW9tX3Zpb2xpbihkcmF3X3F1YW50aWxlcyA9IGMoMC41KSkreWxhYigiU0lGVCBjb252IHJhbmtzY29yZSIpK3hsYWIoIkFidW5kYW5jZSBDbGFzcyIpCnBsb3QoVFBNVF9hYnVuX1NJRlRfY29udikKClRQTVRfYWJ1bl9QT0xZIDwtIGdncGxvdCh0cG10X21lcmdlLCBhZXMoeD1hYnVuZGFuY2VfY2xhc3MsIHk9YXMubnVtZXJpYyhQb2x5cGhlbjJfSERJVl9yYW5rc2NvcmUpKSkgKyBnZW9tX3Zpb2xpbihkcmF3X3F1YW50aWxlcyA9IGMoIDAuNSkpK3lsYWIoIlBvbHlwaGVuMiBIRElWIHJhbmtzY29yZSIpK3hsYWIoIkFidW5kYW5jZSBDbGFzcyIpCnBsb3QoVFBNVF9hYnVuX1BPTFkpCgpUUE1UX2FidW5fUE9MWTEgPC0gZ2dwbG90KHRwbXRfbWVyZ2UsIGFlcyh4PWFidW5kYW5jZV9jbGFzcywgeT1hcy5udW1lcmljKFBvbHlwaGVuMl9IVkFSX3JhbmtzY29yZSkpKSArIGdlb21fdmlvbGluKGRyYXdfcXVhbnRpbGVzID0gYyggMC41KSkreWxhYigiUG9seXBoZW4yIEhWQVIgcmFua3Njb3JlIikreGxhYigiQWJ1bmRhbmNlIENsYXNzIikKcGxvdChUUE1UX2FidW5fUE9MWTEpCmBgYApgYGB7cn0KClByZWRfYWJ1bl9TSUZUIDwtIGdncGxvdCh0cG10X21lcmdlLCBhZXMoYWJ1bmRhbmNlX2NsYXNzKSkgKyBnZW9tX2JhcihhZXMoZmlsbCA9IFNJRlRfcHJlZCkpICsgZ2d0aXRsZSgiQWJ1bmRhbmNlIGNsYXNzIHZzIFNJRlQgcHJlZGljdGlvbiBvZiBEYW1hZ2luZyBvciBUb2xlcmF0ZWQiKQpwbG90KFByZWRfYWJ1bl9TSUZUKQoKdHJpYWxfc2VwIDwtIHRwbXRfbWVyZ2VbYygyMSwyMywyNCwyNildCnRwbXRfbWVyZ2VfZXhwYW5kIDwtIHNlcGFyYXRlX3Jvd3ModHBtdF9tZXJnZSwgYygiUG9seXBoZW4yX0hESVZfc2NvcmUiLCAiUG9seXBoZW4yX0hESVZfcHJlZCIsICJQb2x5cGhlbjJfSFZBUl9zY29yZSIsICJQb2x5cGhlbjJfSFZBUl9wcmVkIikpCgpQcmVkX2FidW5fSFZBUiA8LSBnZ3Bsb3QodHBtdF9tZXJnZV9leHBhbmQsIGFlcyhhYnVuZGFuY2VfY2xhc3MpKSArIGdlb21fYmFyKGFlcyhmaWxsID0gUG9seXBoZW4yX0hWQVJfcHJlZCkpICsgZ2d0aXRsZSgiQWJ1bmRhbmNlIGNsYXNzIHZzIFBvbHlwaGVuMiBIVkFSIHByZWRpY3Rpb25zIikgKyBsYWJzKHN1YnRpdGxlID0gIkQ6IFByb2JhYmx5IERhbWFnaW5nLCBQOiBQb3NzaWJseSBEYW1hZ2luZywgQjogQmVuaWduIikKcGxvdChQcmVkX2FidW5fSFZBUikKCmBgYAoKYGBge3J9CiNjcmVhdGlvbiBvZiBiLXNjb3JlIHRleHQgZmlsZXMgZm9yIHB5bW9sIHVzZQpwdGVuX3B5bW9sIDwtIHN1bW1hcnlTRShwdGVuMV9kYXRhLCBtZWFzdXJldmFyPSJzY29yZSIsIGdyb3VwdmFycz0icG9zaXRpb24iLCBuYS5ybT1UUlVFKQojc2NvcmVbNDA0XSBpcyB3dAp3cml0ZS50YWJsZShwdGVuX3B5bW9sJHNjb3JlWzE6NDAzXSwgInB0ZW5fbWVhbl9zY29yZXNfcHltb2wudHh0Iiwgc2VwPSJcbiIsIHJvdy5uYW1lcz1GLCBjb2wubmFtZXM9RiwgbmEgPSAiTmFOIikKCnRwbXRfcHltb2wgPC0gc3VtbWFyeVNFKHRwbXQxX2RhdGEsIG1lYXN1cmV2YXI9InNjb3JlIiwgZ3JvdXB2YXJzPSJwb3NpdGlvbiIsIG5hLnJtPVRSVUUpCiNzY29yZVs0MDRdIGlzIHd0CndyaXRlLnRhYmxlKHRwbXRfcHltb2wkc2NvcmVbMToyNDVdLCAidHBtdF9tZWFuX3Njb3Jlc19weW1vbC50eHQiLCBzZXA9IlxuIiwgcm93Lm5hbWVzPUYsIGNvbC5uYW1lcz1GLCBuYSA9ICJOYU4iKQpgYGAKCgo=